[asterisk-commits] branch file/coremedia - r7370 in /team/file/coremedia: ./ channels/ include/a...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Dec 6 18:14:59 CST 2005


Author: file
Date: Tue Dec  6 18:14:56 2005
New Revision: 7370

URL: http://svn.digium.com/view/asterisk?rev=7370&view=rev
Log:
Change terminology, expand frame to include sample rate, add basic sample rate stuff to translator and add some codec name parsing

Modified:
    team/file/coremedia/channels/chan_sip.c
    team/file/coremedia/coremedia.c
    team/file/coremedia/frame.c
    team/file/coremedia/include/asterisk/coremedia.h
    team/file/coremedia/include/asterisk/frame.h

Modified: team/file/coremedia/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/file/coremedia/channels/chan_sip.c?rev=7370&r1=7369&r2=7370&view=diff
==============================================================================
--- team/file/coremedia/channels/chan_sip.c (original)
+++ team/file/coremedia/channels/chan_sip.c Tue Dec  6 18:14:56 2005
@@ -11525,8 +11525,6 @@
 		ast_copy_string(p->username, ext, sizeof(p->username));
 		p->fullcontact[0] = 0;	
 	}
-
-	ast_log(LOG_NOTICE, "Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
 
 	//	p->prefcodec = format;
 	ast_mutex_lock(&p->lock);

Modified: team/file/coremedia/coremedia.c
URL: http://svn.digium.com/view/asterisk/team/file/coremedia/coremedia.c?rev=7370&r1=7369&r2=7370&view=diff
==============================================================================
--- team/file/coremedia/coremedia.c (original)
+++ team/file/coremedia/coremedia.c Tue Dec  6 18:14:56 2005
@@ -35,10 +35,13 @@
 
 /* Maximum number of payloads supported */
 #define MAX_PAYLOADS 127
+/* Maximum number of subclasses */
+#define MAX_SUBCLASSES 2500
 
 /* Coremedia entries */
 AST_MUTEX_DEFINE_STATIC(medialock);
 static struct ast_coremedia_entry *ach_root = NULL;
+static struct ast_coremedia_entry *ach_subclass[MAX_SUBCLASSES];
 AST_MUTEX_DEFINE_STATIC(subclasslock);
 static int subclass = 0;
 /* RTP mappings */
@@ -56,12 +59,103 @@
     AST_FORMAT_SLINEAR,
   };
 
+/* Integrated telephone-event */
+static struct ast_coremedia_entry telephone_event =
+  { "telephone-event",
+    TYPE_DTMF,
+    0,
+    8000,
+  };
+
+static struct ast_coremedia_rtp rfc2833_rtp =
+  { "telephone-event",
+    101,
+    0,
+    8000,
+    "telephone-event",
+  };
+
+/* Integrated cisco-event */
+static struct ast_coremedia_entry cisco_event =
+  { "cisco-event",
+    TYPE_DTMF,
+    0,
+    8000,
+  };
+
 /* Initialize the coremedia system */
 void ast_coremedia_init(void)
 {
   /* Embed signed linear passthrough into ourselves */
   ast_coremedia_register(&slinear_entry);
+  ast_coremedia_register(&telephone_event);
+  ast_coremedia_register(&cisco_event);
+  ast_coremedia_rtp_register(&rfc2833_rtp);
+  ast_coremedia_parse_codec("ulaw;g726;g726-16/8000;g726-24/8000");
   return;
+}
+
+/* Parsing helper functions */
+struct ast_coremedia_handle *ast_coremedia_parse_codec(char *codec)
+{
+  char tmp[128] = "";
+  char *codecs = NULL;
+  char *name = NULL, *bitrate2 = NULL, *samples2 = NULL;
+  int bitrate = 0, samples = 8000;
+  struct ast_coremedia_entry *entry = NULL;
+  struct ast_coremedia_handle *return_handle = NULL, *new_handle = NULL;
+
+  /* Simple check */
+  if (codec == NULL)
+    return NULL;
+
+  strncpy(tmp, codec, sizeof(tmp));
+
+  codecs = tmp;
+
+  /* The one time I've ever actually used a do loop for something */
+  do {
+    name = codecs;
+    /* See if there is another codec in the list */
+    codecs = strchr(codecs, ';');
+    if (codecs != NULL) {
+      *codecs = '\0';
+      codecs++;
+    }
+    bitrate2 = strchr(name, '-');
+    if (bitrate2) {
+      *bitrate2 = '\0';
+      bitrate2++;
+      samples2 = strchr(bitrate2, '/');
+    } else {
+      samples2 = strchr(name, '/');
+    }
+    if (samples2) {
+      *samples2 = '\0';
+      samples2++;
+    }
+    /* Sanitize the values slightly */
+    if (bitrate2)
+      bitrate = atoi(bitrate2);
+    else
+      bitrate = 0;
+    if (samples2)
+      samples = atoi(samples2);
+    else
+      samples = 8000;
+    entry = ast_coremedia_get(name, bitrate, samples);
+    if (entry != NULL) {
+      /* Found the entry */
+      new_handle = ast_coremedia_handle_new(entry);
+      if (new_handle == NULL)
+	continue;
+      if (return_handle != NULL)
+	new_handle->next = return_handle;
+      return_handle = new_handle;
+    }
+  } while (codecs);
+
+  return return_handle;
 }
 
 /* Create a brand new shim and attach it to a channel */
@@ -138,6 +232,31 @@
   }
 
   return res;
+}
+
+/* Shuffle the order of a set of coremedia handles backwards */
+struct ast_coremedia_handle *ast_coremedia_handle_shuffle(struct ast_coremedia_handle *existing_handle)
+{
+  struct ast_coremedia_handle *new_list = NULL, *handle = NULL, *dup_handle = NULL, *previous_handle = NULL;
+
+  /* Okay this is really cheesy... essentially iterate through the linked list and add it to a new linked list thus reversing the order */
+  handle = existing_handle;
+  while (handle) {
+    dup_handle = ast_coremedia_handle_new(handle->entry);
+    if (dup_handle != NULL) {
+      if (new_list != NULL)
+	dup_handle->next = new_list;
+      new_list = dup_handle;
+    }
+    previous_handle = handle;
+    /* Move to the next one */
+    handle = handle->next;
+    /* Free the previous one */
+    free(previous_handle);
+    previous_handle = NULL;
+  }
+
+  return new_list;
 }
 
 /* Create a brand new coremedia handle */
@@ -252,10 +371,15 @@
 
   /* Do our pass through the decoder if available */
   if (path->decoder != NULL) {
+    if (frame->sample_rate != path->decoder_entry->sample_rate) {
+      ast_log(LOG_WARNING, "Uh... frame sample rate not that of the decoder... but this is an encoded frame... ah darn!\n");
+    }
     path->decoder->framein(path->dec_state, f);
     frame = path->decoder->frameout(path->dec_state);
     /* Override subclass to be that of the decoder entry */
     frame->subclass = path->decoder_entry->subclass;
+    /* Update frame with output sample rate */
+    frame->sample_rate = path->decoder_entry->sample_rate;
   } else {
     frame = f;
   }
@@ -271,11 +395,21 @@
 
   /* Do our pass through the encoder if available */
   if (path->encoder != NULL) {
+    /* Make sure the incoming sample rate of the frame is acceptable for the encoder */
+    if (frame->sample_rate != path->encoder_entry->sample_rate) {
+      /* We can run this through the sample rate translator because it's signed linear ;) */
+    }
     /* Now run it through this encoder */
     path->encoder->framein(path->enc_state, frame);
     frame = path->encoder->frameout(path->enc_state);
     /* Override subclass to be that of the encoder entry */
     frame->subclass = path->encoder_entry->subclass;
+    /* And override with the sample rate */
+    frame->sample_rate = path->encoder_entry->sample_rate;
+  } else {
+    /* Okay we are feeding out straight signed linear - see if they want it at another sample rate */
+    if (path->sample_rate > 0 && path->sample_rate != frame->sample_rate) {
+    }
   }
 
   /* If we need to consume the given frame... do so */
@@ -361,7 +495,7 @@
   struct ast_coremedia_entry *entry = NULL;
 
   /* Make sure we have a coremedia entry for whichever thing this RTP mapping is for */
-  entry = ast_coremedia_get(rtp->entry_name, rtp->bitrate, rtp->samples);
+  entry = ast_coremedia_get(rtp->entry_name, rtp->bitrate, rtp->sample_rate);
   if (entry == NULL) {
     /* No coremedia entry... either loading order is wrong or this is for a non-existant entry */
     return -1;
@@ -385,7 +519,7 @@
   ast_mutex_unlock(&rtplock);
 
   if (option_verbose > 1)
-    ast_verbose(VERBOSE_PREFIX_2 "Registered RTP mapping %d %s/%d to coremedia handler %s\n", rtp->payload, rtp->name, rtp->samples, rtp->entry->name);
+    ast_verbose(VERBOSE_PREFIX_2 "Registered RTP mapping %d %s/%d to coremedia handler %s\n", rtp->payload, rtp->name, rtp->sample_rate, rtp->entry->name);
 
   return 0;
 }
@@ -400,7 +534,7 @@
     success = 0;
     rtp_root[rtp->payload] = NULL;
     if (option_verbose > 1)
-      ast_verbose(VERBOSE_PREFIX_2 "Unregistered RTP mapping %d %s/%d from coremedia handler %s\n", rtp->payload, rtp->name, rtp->samples, rtp->entry->name);
+      ast_verbose(VERBOSE_PREFIX_2 "Unregistered RTP mapping %d %s/%d from coremedia handler %s\n", rtp->payload, rtp->name, rtp->sample_rate, rtp->entry->name);
   }
   ast_mutex_unlock(&rtplock);
 
@@ -416,8 +550,23 @@
     return "video";
   else if (type == TYPE_DATA)
     return "data";
+  else if (type == TYPE_DTMF)
+    return "dtmf";
   else
     return "unknown";
+}
+
+/* Find a coremedia entry by subclass */
+struct ast_coremedia_entry *ast_coremedia_get_by_subclass(int subclass)
+{
+  struct ast_coremedia_entry *entry = NULL;
+
+  ast_mutex_lock(&medialock);
+  if (ach_subclass[subclass] != NULL)
+    entry = ach_subclass[subclass];
+  ast_mutex_unlock(&medialock);
+
+  return entry;
 }
 
 /* Find a coremedia handler by the old AST_FORMAT system */
@@ -437,15 +586,15 @@
   return entry;
 }
 
-/* Find a coremedia handler by name, bitrate, and samples */
-struct ast_coremedia_entry *ast_coremedia_get(char *name, int bitrate, int samples)
+/* Find a coremedia handler by name, bitrate, and sample rate */
+struct ast_coremedia_entry *ast_coremedia_get(char *name, int bitrate, int sample_rate)
 {
   struct ast_coremedia_entry *entry = NULL;
 
   ast_mutex_lock(&medialock);
   entry = ach_root;
   while (entry) {
-    if (entry->name && !strcasecmp(entry->name, name) && entry->bitrate == bitrate && entry->samples == samples)
+    if (entry->name && !strcasecmp(entry->name, name) && entry->bitrate == bitrate && entry->sample_rate == sample_rate)
       break;
     entry = entry->next;
   }
@@ -466,27 +615,31 @@
   }
   ast_mutex_unlock(&medialock);
 
-  if (option_verbose > 1)
-    ast_verbose(VERBOSE_PREFIX_2 "Linked %s to coremedia handler '%s' of type '%s' with bitrate %d and sample size of %d\n", direction ? "decoder" : "encoder", cm->name, type_to_name(cm->type), cm->bitrate, cm->samples);
+  if (option_verbose > 1) {
+    if (cm->bitrate > 0)
+      ast_verbose(VERBOSE_PREFIX_2 "Linked %s to coremedia handler '%s' of type '%s' with bitrate %d and sample rate of %d\n", direction ? "decoder" : "encoder", cm->name, type_to_name(cm->type), cm->bitrate, cm->sample_rate);
+    else
+      ast_verbose(VERBOSE_PREFIX_2 "Linked %s to coremedia handler '%s' of type '%s' with sample rate of %d\n", direction ? "decoder" : "encoder", cm->name, type_to_name(cm->type), cm->sample_rate);
+  }
 
   return 0;
 }
 
-/* Link a file structure to a coremedia handler by name, bitrate, and samples */
-int ast_coremedia_link_file(char *name, int bitrate, int samples)
+/* Link a file structure to a coremedia handler by name, bitrate, and sample rate */
+int ast_coremedia_link_file(char *name, int bitrate, int sample_rate)
 {
   int success = -1;
 
   return success;
 }
 
-/* Link an encoder or decoder to a coremedia handler by name, bitrate, and samples */
-int ast_coremedia_link_by_data(char *name, int bitrate, int samples, struct ast_coremedia_translator *tl, int direction)
+/* Link an encoder or decoder to a coremedia handler by name, bitrate, and sample rate */
+int ast_coremedia_link_by_data(char *name, int bitrate, int sample_rate, struct ast_coremedia_translator *tl, int direction)
 {
   int success = -1;
   struct ast_coremedia_entry *entry = NULL;
 
-  entry = ast_coremedia_get(name, bitrate, samples);
+  entry = ast_coremedia_get(name, bitrate, sample_rate);
   if (entry != NULL) {
     success = 0;
     ast_coremedia_link(entry, tl, direction);
@@ -501,15 +654,15 @@
   struct ast_coremedia_entry *entry = NULL;
 
   /* Make sure a handler of this information is not already registered */
-  entry = ast_coremedia_get(cm->name, cm->bitrate, cm->samples);
+  entry = ast_coremedia_get(cm->name, cm->bitrate, cm->sample_rate);
   if (entry != NULL) {
     /* Already registered */
     return -1;
   }
 
   /* Sanitize the entry before using it */
-  if (cm->samples == 0)
-    cm->samples = 8000; /* Assume 8000Hz if not specified */
+  if (cm->sample_rate == 0)
+    cm->sample_rate = 8000; /* Assume 8000Hz if not specified */
 
   /* Generate a unique subclass identifier for this coremedia entry */
   ast_mutex_lock(&subclasslock);
@@ -518,7 +671,10 @@
   ast_mutex_unlock(&subclasslock);
 
   if (option_verbose > 1) {
-    ast_verbose(VERBOSE_PREFIX_2 "Registered coremedia handler '%s' of type '%s' with bitrate %d and sample size of %d\n", cm->name, type_to_name(cm->type), cm->bitrate, cm->samples);
+    if (cm->bitrate > 0)
+      ast_verbose(VERBOSE_PREFIX_2 "Registered coremedia handler '%s' of type '%s' with bitrate %d and sample rate of %d\n", cm->name, type_to_name(cm->type), cm->bitrate, cm->sample_rate);
+    else
+      ast_verbose(VERBOSE_PREFIX_2 "Registered coremedia handler '%s' of type '%s' with sample rate of %d\n", cm->name, type_to_name(cm->type), cm->sample_rate);
 
     /* If encoder or decoder is already present... say it's there */
     if (cm->encoder != NULL)
@@ -531,6 +687,8 @@
   ast_mutex_lock(&medialock);
   cm->next = ach_root;
   ach_root = cm;
+  /* Now add it to the subclass array for fast lookup */
+  ach_subclass[cm->subclass] = cm;
   ast_mutex_unlock(&medialock);
 
   return 0;
@@ -544,6 +702,8 @@
 
   /* Locate the entry and remove it from the list */
   ast_mutex_lock(&medialock);
+  /* Remove it from the fast lookup array */
+  ach_subclass[cm->subclass] = NULL;
   entry = ach_root;
   while (entry) {
     if (entry == cm) {
@@ -555,8 +715,12 @@
       }
       /* There should not be any more entries - so break */
       success = 0;
-      if (option_verbose > 1)
-	ast_verbose(VERBOSE_PREFIX_2 "Unregistered coremedia handler '%s' of type '%s' with bitrate %d and sample size of %d\n", cm->name, type_to_name(cm->type), cm->bitrate, cm->samples);
+      if (option_verbose > 1) {
+	if (cm->bitrate > 0)
+	  ast_verbose(VERBOSE_PREFIX_2 "Unregistered coremedia handler '%s' of type '%s' with bitrate %d and sample rate of %d\n", cm->name, type_to_name(cm->type), cm->bitrate, cm->sample_rate);
+	else
+	  ast_verbose(VERBOSE_PREFIX_2 "Unregistered coremedia handler '%s' of type '%s' with sample rate of %d\n", cm->name, type_to_name(cm->type), cm->sample_rate);	
+      }
       break;
     } else {
       previous = entry;

Modified: team/file/coremedia/frame.c
URL: http://svn.digium.com/view/asterisk/team/file/coremedia/frame.c?rev=7370&r1=7369&r2=7370&view=diff
==============================================================================
--- team/file/coremedia/frame.c (original)
+++ team/file/coremedia/frame.c Tue Dec  6 18:14:56 2005
@@ -1184,7 +1184,13 @@
 int ast_codec_get_samples(struct ast_frame *f)
 {
 	int samples=0;
-	switch(f->subclass) {
+	struct ast_coremedia_entry *entry = NULL;
+
+	entry = ast_coremedia_get_by_subclass(f->subclass);
+	if (entry == NULL || entry->format == -1)
+	  return 0;
+
+	switch(entry->format) {
 	case AST_FORMAT_SPEEX:
 		samples = speex_samples(f->data, f->datalen);
 		break;
@@ -1204,8 +1210,7 @@
 		samples = f->datalen / 2;
 		break;
 	case AST_FORMAT_LPC10:
-                /* assumes that the RTP packet contains one LPC10 frame */
-		samples = 22 * 8;
+  		samples = 22 * 8;
 		samples += (((char *)(f->data))[7] & 0x1) * 8;
 		break;
 	case AST_FORMAT_ULAW:
@@ -1217,8 +1222,9 @@
 		samples = f->datalen * 2;
 		break;
 	default:
-		ast_log(LOG_WARNING, "Unable to calculate samples for format %s\n", ast_getformatname(f->subclass));
-	}
+		ast_log(LOG_WARNING, "Unable to calculate samples for format %s\n", ast_getformatname(entry->format));
+	}
+
 	return samples;
 }
 

Modified: team/file/coremedia/include/asterisk/coremedia.h
URL: http://svn.digium.com/view/asterisk/team/file/coremedia/include/asterisk/coremedia.h?rev=7370&r1=7369&r2=7370&view=diff
==============================================================================
--- team/file/coremedia/include/asterisk/coremedia.h (original)
+++ team/file/coremedia/include/asterisk/coremedia.h Tue Dec  6 18:14:56 2005
@@ -38,6 +38,7 @@
 #define TYPE_AUDIO 1
 #define TYPE_VIDEO 2
 #define TYPE_DATA 3
+#define TYPE_DTMF 4
 
   /* Directions */
 #define CM_ENCODE 0
@@ -51,8 +52,8 @@
     int payload;
     /*! Bitrate */
     int bitrate;
-    /*! Samples */
-    int samples;
+    /*! Sample Rate */
+    int sample_rate;
     /*! Name of coremedia entry */
     char *entry_name;
     /*! Registered coremedia entry */
@@ -85,8 +86,8 @@
     int type;
     /*! Bitrate of handler if applicable */
     int bitrate;
-    /*! Samples if applicable - if not defined, assumed to be 8000 */
-    int samples;
+    /*! Sample rate if applicable - if not defined, assumed to be 8000 */
+    int sample_rate;
     /*! The old AST_FORMAT (if applicable) */
     int format;
     /*! Encoder */
@@ -138,6 +139,8 @@
     struct ast_translator_pvt *enc_state;
     /*! Any shims present on this translator path */
     struct ast_coremedia_shim *shims;
+    /* Sample rate of the translator path */
+    int sample_rate;
     /*! Timing is crucial... sorta */
     struct timeval nextin;
     struct timeval nextout;
@@ -146,6 +149,9 @@
   typedef struct ast_coremedia_translator_path ast_coremedia_translator_path_t;
 
   void ast_coremedia_init(void);
+
+  /* String parsing helpers */
+  struct ast_coremedia_handle *ast_coremedia_parse_codec(char *codec);
 
   /* Shims support */
   int ast_coremedia_shimmy(struct ast_channel *channel, struct ast_coremedia_shim *shim, struct ast_coremedia_shim_pvt *pvt, int direction);
@@ -168,14 +174,15 @@
   int ast_coremedia_rtp_unregister(struct ast_coremedia_rtp *rtp);
 
   /* Base entry support */
-  struct ast_coremedia_entry *ast_coremedia_get(char *name, int bitrate, int samples);
+  struct ast_coremedia_entry *ast_coremedia_get(char *name, int bitrate, int sample_rate);
   struct ast_coremedia_entry *ast_coremedia_get_by_format(int format);
+  struct ast_coremedia_entry *ast_coremedia_get_by_subclass(int subclass);
   int ast_coremedia_register(struct ast_coremedia_entry *cm);
   int ast_coremedia_unregister(struct ast_coremedia_entry *cm);
 
   /* Encoder/Decoder Linking */
   int ast_coremedia_link(struct ast_coremedia_entry *cm, struct ast_coremedia_translator *tl, int direction);
-  int ast_coremedia_link_by_data(char *name, int bitrate, int samples, struct ast_coremedia_translator *tl, int direction);
+  int ast_coremedia_link_by_data(char *name, int bitrate, int sample_rate, struct ast_coremedia_translator *tl, int direction);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }

Modified: team/file/coremedia/include/asterisk/frame.h
URL: http://svn.digium.com/view/asterisk/team/file/coremedia/include/asterisk/frame.h?rev=7370&r1=7369&r2=7370&view=diff
==============================================================================
--- team/file/coremedia/include/asterisk/frame.h (original)
+++ team/file/coremedia/include/asterisk/frame.h Tue Dec  6 18:14:56 2005
@@ -105,6 +105,8 @@
 	void *data;		
 	/*! Global delivery time */		
 	struct timeval delivery;
+        /*! Sample Rate */
+        int sample_rate;
 	/*! Next/Prev for linking stand alone frames */
 	struct ast_frame *prev;			
 	/*! Next/Prev for linking stand alone frames */



More information about the asterisk-commits mailing list