codec.c File Reference

Codecs API. More...

#include "asterisk.h"
#include "asterisk/logger.h"
#include "asterisk/codec.h"
#include "asterisk/format.h"
#include "asterisk/frame.h"
#include "asterisk/astobj2.h"
#include "asterisk/strings.h"
#include "asterisk/module.h"
#include "asterisk/cli.h"

Include dependency graph for codec.c:

Go to the source code of this file.

Defines

#define CODEC_BUCKETS   53
 Number of buckets to use for codecs (should be prime for performance reasons).

Functions

int __ast_codec_register (struct ast_codec *codec, struct ast_module *mod)
 This function is used to register a codec with the Asterisk core. Registering allows it to be passed through in frames and configured in channel drivers.
unsigned int ast_codec_determine_length (const struct ast_codec *codec, unsigned int samples)
 Get the length of media (in milliseconds) given a number of samples.
struct ast_codecast_codec_get (const char *name, enum ast_media_type type, unsigned int sample_rate)
 Retrieve a codec given a name, type, and sample rate.
struct ast_codecast_codec_get_by_id (int id)
 Retrieve a codec given the unique identifier.
int ast_codec_get_max (void)
 Retrieve the current maximum identifier for codec iteration.
int ast_codec_init (void)
 Initialize codec support within the core.
const char * ast_codec_media_type2str (enum ast_media_type type)
 Conversion function to take a media type and turn it into a string.
unsigned int ast_codec_samples_count (struct ast_frame *frame)
 Get the number of samples contained within a frame.
static int codec_cmp (void *obj, void *arg, int flags)
static void codec_dtor (void *obj)
static int codec_hash (const void *obj, int flags)
static int codec_id_cmp (void *obj, void *arg, int flags)
 Callback function for getting a codec based on unique identifier.
static void codec_shutdown (void)
 Function called when the process is shutting down.
static char * show_codec (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * show_codecs (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)

Variables

static struct ast_cli_entry codec_cli []
static int codec_id = 1
 Current identifier value for newly registered codec.
static struct ao2_containercodecs
 Registered codecs.


Detailed Description

Codecs API.

Author:
Joshua Colp <jcolp@digium.com>

Definition in file codec.c.


Define Documentation

#define CODEC_BUCKETS   53

Number of buckets to use for codecs (should be prime for performance reasons).

Definition at line 44 of file codec.c.

Referenced by ast_codec_init().


Function Documentation

int __ast_codec_register ( struct ast_codec codec,
struct ast_module mod 
)

This function is used to register a codec with the Asterisk core. Registering allows it to be passed through in frames and configured in channel drivers.

Parameters:
codec to register
mod the module this codec is provided by
Return values:
0 success
-1 failure

Definition at line 262 of file codec.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_find, ao2_link_flags, ao2_ref, ao2_t_alloc_options, ast_codec_media_type2str(), ast_log, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_UNKNOWN, ast_module_shutdown_ref, ast_verb, codec_dtor(), ast_codec::description, ast_codec::id, lock, LOG_ERROR, ast_codec::name, OBJ_NOLOCK, OBJ_SEARCH_OBJECT, S_OR, ast_codec::sample_rate, SCOPED_AO2WRLOCK, and ast_codec::type.

00263 {
00264    SCOPED_AO2WRLOCK(lock, codecs);
00265    struct ast_codec *codec_new;
00266 
00267    /* Some types have specific requirements */
00268    if (codec->type == AST_MEDIA_TYPE_UNKNOWN) {
00269       ast_log(LOG_ERROR, "A media type must be specified for codec '%s'\n", codec->name);
00270       return -1;
00271    } else if (codec->type == AST_MEDIA_TYPE_AUDIO) {
00272       if (!codec->sample_rate) {
00273          ast_log(LOG_ERROR, "A sample rate must be specified for codec '%s' of type '%s'\n",
00274             codec->name, ast_codec_media_type2str(codec->type));
00275          return -1;
00276       }
00277    }
00278 
00279    codec_new = ao2_find(codecs, codec, OBJ_SEARCH_OBJECT | OBJ_NOLOCK);
00280    if (codec_new) {
00281       ast_log(LOG_ERROR, "A codec with name '%s' of type '%s' and sample rate '%u' is already registered\n",
00282          codec->name, ast_codec_media_type2str(codec->type), codec->sample_rate);
00283       ao2_ref(codec_new, -1);
00284       return -1;
00285    }
00286 
00287    codec_new = ao2_t_alloc_options(sizeof(*codec_new), codec_dtor,
00288       AO2_ALLOC_OPT_LOCK_NOLOCK, S_OR(codec->description, ""));
00289    if (!codec_new) {
00290       ast_log(LOG_ERROR, "Could not allocate a codec with name '%s' of type '%s' and sample rate '%u'\n",
00291          codec->name, ast_codec_media_type2str(codec->type), codec->sample_rate);
00292       return -1;
00293    }
00294    *codec_new = *codec;
00295    codec_new->id = codec_id++;
00296 
00297    ao2_link_flags(codecs, codec_new, OBJ_NOLOCK);
00298 
00299    /* Once registered a codec can not be unregistered, and the module must persist until shutdown */
00300    ast_module_shutdown_ref(mod);
00301 
00302    ast_verb(2, "Registered '%s' codec '%s' at sample rate '%u' with id '%u'\n",
00303       ast_codec_media_type2str(codec->type), codec->name, codec->sample_rate, codec_new->id);
00304 
00305    ao2_ref(codec_new, -1);
00306 
00307    return 0;
00308 }

unsigned int ast_codec_determine_length ( const struct ast_codec codec,
unsigned int  samples 
)

Get the length of media (in milliseconds) given a number of samples.

Parameters:
codec The codec itself
samples The number of samples
Return values:
length of media (in milliseconds)

Definition at line 371 of file codec.c.

References ast_codec::get_length.

Referenced by ast_format_determine_length().

00372 {
00373    if (!codec->get_length) {
00374       return 0;
00375    }
00376 
00377    return codec->get_length(samples);
00378 }

struct ast_codec* ast_codec_get ( const char *  name,
enum ast_media_type  type,
unsigned int  sample_rate 
) [read]

Retrieve a codec given a name, type, and sample rate.

Parameters:
name The name of the codec
type The type of the codec
sample_rate Optional sample rate, may not be applicable for some types
Return values:
non-NULL success
NULL failure
Note:
The returned codec is reference counted and ao2_ref or ao2_cleanup must be used to release the reference.

Definition at line 310 of file codec.c.

References ao2_find, ast_codec::name, and OBJ_SEARCH_OBJECT.

Referenced by __ast_register_translator(), AST_TEST_DEFINE(), handle_show_translation_path(), and newpvt().

00311 {
00312    struct ast_codec codec = {
00313       .name = name,
00314       .type = type,
00315       .sample_rate = sample_rate,
00316    };
00317 
00318    return ao2_find(codecs, &codec, OBJ_SEARCH_OBJECT);
00319 }

struct ast_codec* ast_codec_get_by_id ( int  id  )  [read]

Retrieve a codec given the unique identifier.

Parameters:
id The unique identifier
Return values:
non-NULL success
NULL failure
Note:
Identifiers start at 1 so if iterating don't start at 0.

The returned codec is reference counted and ao2_ref or ao2_cleanup must be used to release the reference.

Definition at line 321 of file codec.c.

References ao2_callback, and codec_id_cmp().

Referenced by ast_format_cap_append_by_type(), AST_TEST_DEFINE(), complete_trans_path_choice(), data_add_codec(), handle_show_translation_path(), handle_show_translation_table(), and index2codec().

00322 {
00323    return ao2_callback(codecs, 0, codec_id_cmp, &id);
00324 }

int ast_codec_get_max ( void   ) 

Retrieve the current maximum identifier for codec iteration.

Returns:
Maximum codec identifier

Definition at line 326 of file codec.c.

Referenced by ast_format_cap_append_by_type(), and AST_TEST_DEFINE().

00327 {
00328    return codec_id;
00329 }

int ast_codec_init ( void   ) 

Initialize codec support within the core.

Return values:
0 success
-1 failure

Definition at line 240 of file codec.c.

References AO2_ALLOC_OPT_LOCK_RWLOCK, ao2_container_alloc_options, ARRAY_LEN, ast_cli_register_multiple(), ast_register_cleanup(), CODEC_BUCKETS, codec_cmp(), codec_hash(), and codec_shutdown().

Referenced by main().

00241 {
00242    codecs = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_RWLOCK, CODEC_BUCKETS, codec_hash, codec_cmp);
00243    if (!codecs) {
00244       return -1;
00245    }
00246 
00247    ast_cli_register_multiple(codec_cli, ARRAY_LEN(codec_cli));
00248    ast_register_cleanup(codec_shutdown);
00249 
00250    return 0;
00251 }

const char* ast_codec_media_type2str ( enum ast_media_type  type  ) 

Conversion function to take a media type and turn it into a string.

Parameters:
type The media type
Return values:
string representation of the media type

Definition at line 331 of file codec.c.

References AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_IMAGE, AST_MEDIA_TYPE_TEXT, and AST_MEDIA_TYPE_VIDEO.

Referenced by __ast_codec_register(), ast_rtp_engine_load_format(), ast_rtp_read(), and show_codecs().

00332 {
00333    switch (type) {
00334    case AST_MEDIA_TYPE_AUDIO:
00335       return "audio";
00336    case AST_MEDIA_TYPE_VIDEO:
00337       return "video";
00338    case AST_MEDIA_TYPE_IMAGE:
00339       return "image";
00340    case AST_MEDIA_TYPE_TEXT:
00341       return "text";
00342    default:
00343       return "<unknown>";
00344    }
00345 }

unsigned int ast_codec_samples_count ( struct ast_frame frame  ) 

Get the number of samples contained within a frame.

Parameters:
frame The frame itself
Return values:
number of samples in the frame

Definition at line 347 of file codec.c.

References ao2_ref, ast_format_get_codec(), ast_format_get_name(), AST_FRAME_IMAGE, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log, ast_frame_subclass::format, ast_frame::frametype, LOG_WARNING, ast_codec::samples_count, and ast_frame::subclass.

Referenced by ast_rtp_read(), dahdi_encoder_frameout(), isAnsweringMachine(), moh_generate(), schedule_delivery(), socket_process_helper(), and socket_process_meta().

00348 {
00349    struct ast_codec *codec;
00350    unsigned int samples = 0;
00351 
00352    if ((frame->frametype != AST_FRAME_VOICE) &&
00353       (frame->frametype != AST_FRAME_VIDEO) &&
00354       (frame->frametype != AST_FRAME_IMAGE)) {
00355       return 0;
00356    }
00357 
00358    codec = ast_format_get_codec(frame->subclass.format);
00359 
00360    if (codec->samples_count) {
00361       samples = codec->samples_count(frame);
00362    } else {
00363       ast_log(LOG_WARNING, "Unable to calculate samples for codec %s\n",
00364          ast_format_get_name(frame->subclass.format));
00365    }
00366 
00367    ao2_ref(codec, -1);
00368    return samples;
00369 }

static int codec_cmp ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 71 of file codec.c.

References ast_assert, AST_MEDIA_TYPE_UNKNOWN, CMP_MATCH, ast_codec::name, OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, OBJ_SEARCH_PARTIAL_KEY, ast_codec::sample_rate, and ast_codec::type.

Referenced by ast_codec_init().

00072 {
00073    const struct ast_codec *left = obj;
00074    const struct ast_codec *right = arg;
00075    const char *right_key = arg;
00076    int cmp;
00077 
00078    switch (flags & OBJ_SEARCH_MASK) {
00079    case OBJ_SEARCH_OBJECT:
00080       right_key = right->name;
00081       cmp = strcmp(left->name, right_key);
00082 
00083       if (right->type != AST_MEDIA_TYPE_UNKNOWN) {
00084          cmp |= (right->type != left->type);
00085       }
00086 
00087       /* BUGBUG: this will allow a match on a codec by name only.
00088        * This is particularly useful when executed by the CLI; if
00089        * that is not needed in translate.c, this can be removed.
00090        */
00091       if (right->sample_rate) {
00092          cmp |= (right->sample_rate != left->sample_rate);
00093       }
00094       break;
00095    case OBJ_SEARCH_KEY:
00096       cmp = strcmp(left->name, right_key);
00097       break;
00098    case OBJ_SEARCH_PARTIAL_KEY:
00099       cmp = strncmp(left->name, right_key, strlen(right_key));
00100       break;
00101    default:
00102       ast_assert(0);
00103       cmp = 0;
00104       break;
00105    }
00106    if (cmp) {
00107       return 0;
00108    }
00109 
00110    return CMP_MATCH;
00111 }

static void codec_dtor ( void *  obj  )  [static]

Definition at line 253 of file codec.c.

References ast_module_unref, and ast_codec::mod.

Referenced by __ast_codec_register().

00254 {
00255    struct ast_codec *codec;
00256 
00257    codec = obj;
00258 
00259    ast_module_unref(codec->mod);
00260 }

static int codec_hash ( const void *  obj,
int  flags 
) [static]

Definition at line 52 of file codec.c.

References ast_assert, ast_str_hash(), ast_codec::name, OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, and OBJ_SEARCH_OBJECT.

Referenced by ast_codec_init().

00053 {
00054    const struct ast_codec *codec;
00055    const char *key;
00056 
00057    switch (flags & OBJ_SEARCH_MASK) {
00058    case OBJ_SEARCH_KEY:
00059       key = obj;
00060       return ast_str_hash(key);
00061    case OBJ_SEARCH_OBJECT:
00062       codec = obj;
00063       return ast_str_hash(codec->name);
00064    default:
00065       /* Hash can only work on something with a full key. */
00066       ast_assert(0);
00067       return 0;
00068    }
00069 }

static int codec_id_cmp ( void *  obj,
void *  arg,
int  flags 
) [static]

Callback function for getting a codec based on unique identifier.

Definition at line 181 of file codec.c.

References CMP_MATCH, CMP_STOP, and ast_codec::id.

Referenced by ast_codec_get_by_id(), and show_codec().

00182 {
00183    struct ast_codec *codec = obj;
00184    int *id = arg;
00185 
00186    return (codec->id == *id) ? CMP_MATCH | CMP_STOP : 0;
00187 }

static void codec_shutdown ( void   )  [static]

Function called when the process is shutting down.

Definition at line 233 of file codec.c.

References ao2_cleanup, ARRAY_LEN, ast_cli_unregister_multiple(), and NULL.

Referenced by ast_codec_init().

static char* show_codec ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 189 of file codec.c.

References ao2_callback, ao2_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, codec_id_cmp(), ast_cli_entry::command, ast_codec::description, ast_cli_args::fd, ast_codec::id, NULL, and ast_cli_entry::usage.

00190 {
00191    int type_punned_codec;
00192    struct ast_codec *codec;
00193 
00194    switch (cmd) {
00195    case CLI_INIT:
00196       e->command = "core show codec";
00197       e->usage =
00198          "Usage: core show codec <number>\n"
00199          "       Displays codec mapping\n";
00200       return NULL;
00201    case CLI_GENERATE:
00202       return NULL;
00203    }
00204 
00205    if (a->argc != 4) {
00206       return CLI_SHOWUSAGE;
00207    }
00208 
00209    if (sscanf(a->argv[3], "%30d", &type_punned_codec) != 1) {
00210       return CLI_SHOWUSAGE;
00211    }
00212 
00213    codec = ao2_callback(codecs, 0, codec_id_cmp, &type_punned_codec);
00214    if (!codec) {
00215       ast_cli(a->fd, "Codec %d not found\n", type_punned_codec);
00216       return CLI_SUCCESS;
00217    }
00218 
00219    ast_cli(a->fd, "%11u %s\n", (unsigned int) codec->id, codec->description);
00220 
00221    ao2_ref(codec, -1);
00222 
00223    return CLI_SUCCESS;
00224 }

static char* show_codecs ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 113 of file codec.c.

References ao2_iterator_destroy(), AO2_ITERATOR_DONTLOCK, ao2_iterator_init(), ao2_iterator_next, ao2_rdlock, ao2_ref, ao2_unlock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_codec_media_type2str(), AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_IMAGE, AST_MEDIA_TYPE_TEXT, AST_MEDIA_TYPE_VIDEO, ast_opt_dont_warn, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_codec::description, ast_cli_args::fd, ast_codec::id, ast_codec::name, NULL, ast_codec::type, and ast_cli_entry::usage.

00114 {
00115    struct ao2_iterator i;
00116    struct ast_codec *codec;
00117 
00118    switch (cmd) {
00119    case CLI_INIT:
00120       e->command = "core show codecs [audio|video|image|text]";
00121       e->usage =
00122          "Usage: core show codecs [audio|video|image|text]\n"
00123          "       Displays codec mapping\n";
00124       return NULL;
00125    case CLI_GENERATE:
00126       return NULL;
00127    }
00128 
00129    if ((a->argc < 3) || (a->argc > 4)) {
00130       return CLI_SHOWUSAGE;
00131    }
00132 
00133    if (!ast_opt_dont_warn) {
00134       ast_cli(a->fd, "Disclaimer: this command is for informational purposes only.\n"
00135             "\tIt does not indicate anything about your configuration.\n");
00136    }
00137 
00138    ast_cli(a->fd, "%8s %5s %8s %s\n","ID","TYPE","NAME","DESCRIPTION");
00139    ast_cli(a->fd, "-----------------------------------------------------------------------------------\n");
00140 
00141    ao2_rdlock(codecs);
00142    i = ao2_iterator_init(codecs, AO2_ITERATOR_DONTLOCK);
00143 
00144    for (; (codec = ao2_iterator_next(&i)); ao2_ref(codec, -1)) {
00145       if (a->argc == 4) {
00146          if (!strcasecmp(a->argv[3], "audio")) {
00147             if (codec->type != AST_MEDIA_TYPE_AUDIO) {
00148                continue;
00149             }
00150          } else if (!strcasecmp(a->argv[3], "video")) {
00151             if (codec->type != AST_MEDIA_TYPE_VIDEO) {
00152                continue;
00153             }
00154          } else if (!strcasecmp(a->argv[3], "image")) {
00155             if (codec->type != AST_MEDIA_TYPE_IMAGE) {
00156                continue;
00157             }
00158          } else if (!strcasecmp(a->argv[3], "text")) {
00159             if (codec->type != AST_MEDIA_TYPE_TEXT) {
00160                continue;
00161             }
00162          } else {
00163             continue;
00164          }
00165       }
00166 
00167       ast_cli(a->fd, "%8u %5s %8s (%s)\n",
00168          codec->id,
00169          ast_codec_media_type2str(codec->type),
00170          codec->name,
00171          codec->description);
00172    }
00173 
00174    ao2_iterator_destroy(&i);
00175    ao2_unlock(codecs);
00176 
00177    return CLI_SUCCESS;
00178 }


Variable Documentation

struct ast_cli_entry codec_cli[] [static]

Initial value:

 {
   AST_CLI_DEFINE(show_codecs, "Displays a list of registered codecs"),
   AST_CLI_DEFINE(show_codec, "Shows a specific codec"),
}

Definition at line 227 of file codec.c.

int codec_id = 1 [static]

Current identifier value for newly registered codec.

Definition at line 47 of file codec.c.

struct ao2_container* codecs [static]

Registered codecs.

Definition at line 50 of file codec.c.

Referenced by action_originate(), ast_data_add_codec(), ast_data_add_codecs(), handle_capabilities_res_message(), and process_sdp().


Generated on Thu Apr 16 06:30:13 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6