Asterisk - The Open Source Telephony Project GIT-master-0644429
format.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2014, Digium, Inc.
5 *
6 * Joshua Colp <jcolp@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*! \file
20 *
21 * \brief Media Format API
22 *
23 * \author Joshua Colp <jcolp@digium.com>
24 */
25
26/*** MODULEINFO
27 <support_level>core</support_level>
28 ***/
29
30#include "asterisk.h"
31
32#include "asterisk/logger.h"
33#include "asterisk/codec.h"
34#include "asterisk/format.h"
35#include "asterisk/astobj2.h"
36#include "asterisk/strings.h"
37#include "asterisk/module.h"
38
39/*! \brief Number of buckets to use for format interfaces (should be prime for performance reasons) */
40#define FORMAT_INTERFACE_BUCKETS 53
41
42/*! \brief Definition of a media format */
43struct ast_format {
44 /*! Name of the format */
45 const char *name;
46 /*! \brief Pointer to the codec in use for this format */
48 /*! \brief Attribute specific data, implementation specific */
50 /*! \brief Pointer to the optional format interface */
52 /*! \brief The number if audio channels used, if more than one an interleaved format is required */
53 unsigned int channel_count;
54};
55
56/*! \brief Structure used when registering a format interface */
58 /*! \brief Pointer to the format interface itself */
60 /*! \brief Name of the codec the interface is for */
61 char codec[0];
62};
63
64/*! \brief Container for registered format interfaces */
66
69
70/*! \brief Function called when the process is shutting down */
71static void format_shutdown(void)
72{
75}
76
78{
80 FORMAT_INTERFACE_BUCKETS, format_interface_hash_fn, NULL, format_interface_cmp_fn);
81 if (!interfaces) {
82 return -1;
83 }
84
86
87 return 0;
88}
89
90int __ast_format_interface_register(const char *codec, const struct ast_format_interface *interface, struct ast_module *mod)
91{
94
96 ast_log(LOG_ERROR, "Format interface for codec '%s' does not implement required callbacks\n", codec);
97 return -1;
98 }
99
101 if (format_interface) {
102 ast_log(LOG_ERROR, "A format interface is already present for codec '%s'\n", codec);
104 return -1;
105 }
106
109 if (!format_interface) {
110 return -1;
111 }
113 strcpy(format_interface->codec, codec); /* Safe */
114
115 /* Once registered a format interface cannot be unregistered. */
119
120 ast_verb(5, "Registered format interface for codec '%s'\n", codec);
121
122 return 0;
123}
124
125void *ast_format_get_attribute_data(const struct ast_format *format)
126{
127 return format->attribute_data;
128}
129
130void ast_format_set_attribute_data(struct ast_format *format, void *attribute_data)
131{
132 format->attribute_data = attribute_data;
133}
134
135unsigned int ast_format_get_channel_count(const struct ast_format *format)
136{
137 return format->channel_count;
138}
139
140void ast_format_set_channel_count(struct ast_format *format, unsigned int channel_count)
141{
142 format->channel_count = channel_count;
143}
144
145/*! \brief Destructor for media formats */
146static void format_destroy(void *obj)
147{
148 struct ast_format *format = obj;
149
150 if (format->interface) {
151 format->interface->format_destroy(format);
152 }
153
154 ao2_cleanup(format->codec);
155}
156
157struct ast_format *ast_format_create_named(const char *format_name, struct ast_codec *codec)
158{
159 struct ast_format *format;
161
162 format = ao2_t_alloc_options(sizeof(*format), format_destroy,
163 AO2_ALLOC_OPT_LOCK_NOLOCK, S_OR(codec->description, ""));
164 if (!format) {
165 return NULL;
166 }
167 format->name = format_name;
168 format->codec = ao2_bump(codec);
169 format->channel_count = 1;
170
172 if (format_interface) {
175 }
176
177 return format;
178}
179
180struct ast_format *ast_format_clone(const struct ast_format *format)
181{
182 struct ast_format *cloned = ast_format_create_named(format->name, format->codec);
183
184 if (!cloned) {
185 return NULL;
186 }
187
188 if (cloned->interface && cloned->interface->format_clone(format, cloned)) {
189 ao2_ref(cloned, -1);
190 return NULL;
191 }
192
193 return cloned;
194}
195
197{
199}
200
201enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
202{
203 const struct ast_format_interface *interface;
204
205 if (format1 == NULL || format2 == NULL) {
207 }
208
209 if (format1 == format2) {
211 }
212
213 if (format1->codec != format2->codec) {
215 }
216
217 interface = format1->interface ? format1->interface : format2->interface;
218
219 if (interface && interface->format_cmp) {
220 return interface->format_cmp(format1, format2);
221 }
222
224}
225
226struct ast_format *ast_format_joint(const struct ast_format *format1, const struct ast_format *format2)
227{
228 const struct ast_format_interface *interface;
229
230 if (format1->codec != format2->codec) {
231 return NULL;
232 }
233
234 /* If the two formats are the same structure OR if the codec is the same and no attributes
235 * exist we can immediately return a format with reference count bumped up, since they are
236 * the same.
237 */
238 if ((ast_format_cmp(format1, format2) == AST_FORMAT_CMP_EQUAL && !format1->attribute_data && !format2->attribute_data)) {
239 return ao2_bump((struct ast_format*)format1);
240 }
241
242 interface = format1->interface ? format1->interface : format2->interface;
243
244 /* If there is attribute data on either there has to be an interface */
245 return interface->format_get_joint(format1, format2);
246}
247
248struct ast_format *ast_format_attribute_set(const struct ast_format *format, const char *name, const char *value)
249{
250 const struct ast_format_interface *interface = format->interface;
251
252 if (!interface) {
253 struct format_interface *format_interface = ao2_find(interfaces, format->codec->name, OBJ_SEARCH_KEY);
254 if (format_interface) {
255 interface = format_interface->interface;
257 }
258 }
259
261 return ao2_bump((struct ast_format*)format);
262 }
263
264 return interface->format_attribute_set(format, name, value);
265}
266
267const void *ast_format_attribute_get(const struct ast_format *format, const char *name)
268{
269 const struct ast_format_interface *interface = format->interface;
270
271 if (!interface) {
273 if (format_interface) {
274 interface = format_interface->interface;
276 }
277 }
278
280 return NULL;
281 }
282
283 return interface->format_attribute_get(format, name);
284}
285
286struct ast_format *ast_format_parse_sdp_fmtp(const struct ast_format *format, const char *attributes)
287{
288 const struct ast_format_interface *interface = format->interface;
289
290 if (!interface) {
292 if (format_interface) {
293 interface = format_interface->interface;
295 }
296 }
297
299 return ao2_bump((struct ast_format*)format);
300 }
301
302 return interface->format_parse_sdp_fmtp(format, attributes);
303}
304
305void ast_format_generate_sdp_fmtp(const struct ast_format *format, unsigned int payload, struct ast_str **str)
306{
307 const struct ast_format_interface *interface = format->interface;
308
309 if (!interface) {
311 if (format_interface) {
312 interface = format_interface->interface;
314 }
315 }
316
318 return;
319 }
320
321 interface->format_generate_sdp_fmtp(format, payload, str);
322}
323
324struct ast_codec *ast_format_get_codec(const struct ast_format *format)
325{
326 return ao2_bump(format->codec);
327}
328
329unsigned int ast_format_get_codec_id(const struct ast_format *format)
330{
331 return format->codec->id;
332}
333
334const char *ast_format_get_name(const struct ast_format *format)
335{
336 return format->name;
337}
338
339const char *ast_format_get_codec_name(const struct ast_format *format)
340{
341 return format->codec->name;
342}
343
344int ast_format_can_be_smoothed(const struct ast_format *format)
345{
346 return format->codec->smooth;
347}
348
350{
351 return format->codec->smoother_flags;
352}
353
355{
356 return format->codec->type;
357}
358
359unsigned int ast_format_get_default_ms(const struct ast_format *format)
360{
361 return format->codec->default_ms;
362}
363
364unsigned int ast_format_get_minimum_ms(const struct ast_format *format)
365{
366 return format->codec->minimum_ms;
367}
368
369unsigned int ast_format_get_maximum_ms(const struct ast_format *format)
370{
371 return format->codec->maximum_ms;
372}
373
374unsigned int ast_format_get_minimum_bytes(const struct ast_format *format)
375{
376 return format->codec->minimum_bytes;
377}
378
379unsigned int ast_format_get_sample_rate(const struct ast_format *format)
380{
381 return format->codec->sample_rate ?: 8000;
382}
383
384unsigned int ast_format_determine_length(const struct ast_format *format, unsigned int samples)
385{
386 return ast_codec_determine_length(format->codec, samples);
387}
const char * str
Definition: app_jack.c:147
ast_mutex_t lock
Definition: app_sla.c:331
if(!yyg->yy_init)
Definition: ast_expr2f.c:854
Asterisk main include file. File version handling, generic pbx functions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#define ast_log
Definition: astobj2.c:42
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
@ AO2_ALLOC_OPT_LOCK_RWLOCK
Definition: astobj2.h:365
#define AO2_STRING_FIELD_CMP_FN(stype, field)
Creates a compare function for a structure string field.
Definition: astobj2.h:2048
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
Definition: astobj2.h:1554
#define ao2_t_alloc_options(data_size, destructor_fn, options, debug_msg)
Allocate and initialize an object.
Definition: astobj2.h:402
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
#define AO2_STRING_FIELD_HASH_FN(stype, field)
Creates a hash function for a structure string field.
Definition: astobj2.h:2032
@ OBJ_NOLOCK
Assume that the ao2_container is already locked.
Definition: astobj2.h:1063
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
Codec API.
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.
Definition: codec.c:408
ast_media_type
Types of media.
Definition: codec.h:30
int ast_format_get_smoother_flags(const struct ast_format *format)
Get smoother flags for this format.
Definition: format.c:349
int __ast_format_interface_register(const char *codec, const struct ast_format_interface *interface, struct ast_module *mod)
Register a format interface for use with the provided codec.
Definition: format.c:90
enum ast_media_type ast_format_get_type(const struct ast_format *format)
Get the media type of a format.
Definition: format.c:354
unsigned int ast_format_get_codec_id(const struct ast_format *format)
Get the codec identifier associated with a format.
Definition: format.c:329
struct ast_codec * ast_format_get_codec(const struct ast_format *format)
Get the codec associated with a format.
Definition: format.c:324
struct ast_format * ast_format_attribute_set(const struct ast_format *format, const char *name, const char *value)
Set an attribute on a format to a specific value.
Definition: format.c:248
static void format_destroy(void *obj)
Destructor for media formats.
Definition: format.c:146
int ast_format_can_be_smoothed(const struct ast_format *format)
Get whether or not the format can be smoothed.
Definition: format.c:344
void ast_format_set_channel_count(struct ast_format *format, unsigned int channel_count)
Set the channel count on a format.
Definition: format.c:140
void * ast_format_get_attribute_data(const struct ast_format *format)
Get the attribute data on a format.
Definition: format.c:125
unsigned int ast_format_get_minimum_bytes(const struct ast_format *format)
Get the minimum number of bytes expected in a frame for this format.
Definition: format.c:374
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition: format.c:379
struct ast_format * ast_format_create_named(const char *format_name, struct ast_codec *codec)
Create a new media format with a specific name.
Definition: format.c:157
unsigned int ast_format_get_minimum_ms(const struct ast_format *format)
Get the minimum amount of media carried in this format.
Definition: format.c:364
struct ast_format * ast_format_joint(const struct ast_format *format1, const struct ast_format *format2)
Get a common joint capability between two formats.
Definition: format.c:226
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
void ast_format_set_attribute_data(struct ast_format *format, void *attribute_data)
Set the attribute data on a format.
Definition: format.c:130
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
struct ast_format * ast_format_clone(const struct ast_format *format)
Clone an existing media format so it can be modified.
Definition: format.c:180
const char * ast_format_get_codec_name(const struct ast_format *format)
Get the codec name associated with a format.
Definition: format.c:339
const void * ast_format_attribute_get(const struct ast_format *format, const char *name)
Definition: format.c:267
unsigned int ast_format_determine_length(const struct ast_format *format, unsigned int samples)
Get the length (in milliseconds) for the format with a given number of samples.
Definition: format.c:384
void ast_format_generate_sdp_fmtp(const struct ast_format *format, unsigned int payload, struct ast_str **str)
This function is used to produce an fmtp SDP line for an Asterisk format. The attributes present on t...
Definition: format.c:305
#define FORMAT_INTERFACE_BUCKETS
Number of buckets to use for format interfaces (should be prime for performance reasons)
Definition: format.c:40
unsigned int ast_format_get_default_ms(const struct ast_format *format)
Get the default framing size (in milliseconds) for a format.
Definition: format.c:359
struct ast_format * ast_format_parse_sdp_fmtp(const struct ast_format *format, const char *attributes)
This function is used to have a media format aware module parse and interpret SDP attribute informati...
Definition: format.c:286
static void format_shutdown(void)
Function called when the process is shutting down.
Definition: format.c:71
struct ast_format * ast_format_create(struct ast_codec *codec)
Create a new media format.
Definition: format.c:196
unsigned int ast_format_get_channel_count(const struct ast_format *format)
Get the channel count on a format.
Definition: format.c:135
static struct ao2_container * interfaces
Container for registered format interfaces.
Definition: format.c:65
unsigned int ast_format_get_maximum_ms(const struct ast_format *format)
Get the maximum amount of media carried in this format.
Definition: format.c:369
int ast_format_init(void)
Initialize media format support.
Definition: format.c:77
Media Format API.
ast_format_cmp_res
Format comparison results.
Definition: format.h:34
@ AST_FORMAT_CMP_EQUAL
Definition: format.h:36
@ AST_FORMAT_CMP_NOT_EQUAL
Definition: format.h:38
static const char name[]
Definition: format_mp3.c:68
Support for logging to various files, console and syslog Configuration in file logger....
#define LOG_ERROR
#define ast_verb(level,...)
#define SCOPED_AO2WRLOCK(varname, obj)
scoped lock specialization for ao2 write locks.
Definition: lock.h:614
Asterisk module definitions.
#define ast_module_shutdown_ref(mod)
Prevent unload of the module before shutdown.
Definition: module.h:478
#define NULL
Definition: resample.c:96
String manipulation functions.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
Generic container type.
Represents a media codec within Asterisk.
Definition: codec.h:42
unsigned int sample_rate
Sample rate (number of samples carried in a second)
Definition: codec.h:52
unsigned int maximum_ms
Maximum length of media that can be carried (in milliseconds) in a frame.
Definition: codec.h:56
unsigned int minimum_bytes
Length in bytes of the data payload of a minimum_ms frame.
Definition: codec.h:60
unsigned int smoother_flags
Flags to be passed to the smoother.
Definition: codec.h:80
unsigned int default_ms
Default length of media carried (in milliseconds) in a frame.
Definition: codec.h:58
enum ast_media_type type
Type of media this codec contains.
Definition: codec.h:50
unsigned int minimum_ms
Minimum length of media that can be carried (in milliseconds) in a frame.
Definition: codec.h:54
unsigned int smooth
Whether the media can be smoothed or not.
Definition: codec.h:78
const char * name
Name for this codec.
Definition: codec.h:46
unsigned int id
Internal unique identifier for this codec, set at registration time (starts at 1)
Definition: codec.h:44
Optional format interface to extend format operations.
Definition: format.h:44
struct ast_format *(*const format_attribute_set)(const struct ast_format *format, const char *name, const char *value)
Set an attribute on a format.
Definition: format.h:98
void(*const format_destroy)(struct ast_format *format)
Callback for when the format is destroyed, used to release attribute resources.
Definition: format.h:50
void(*const format_generate_sdp_fmtp)(const struct ast_format *format, unsigned int payload, struct ast_str **str)
Generate SDP attribute information from an ast_format structure.
Definition: format.h:121
int(*const format_clone)(const struct ast_format *src, struct ast_format *dst)
Callback for when the format is cloned, used to clone attributes.
Definition: format.h:61
struct ast_format *(*const format_parse_sdp_fmtp)(const struct ast_format *format, const char *attributes)
Parse SDP attribute information, interpret it, and store it in the format structure.
Definition: format.h:110
const void *(*const format_attribute_get)(const struct ast_format *format, const char *name)
Retrieve a particular format attribute setting.
Definition: format.h:134
enum ast_format_cmp_res(*const format_cmp)(const struct ast_format *format1, const struct ast_format *format2)
Determine if format 1 is a subset of format 2.
Definition: format.h:71
Definition of a media format.
Definition: format.c:43
struct ast_codec * codec
Pointer to the codec in use for this format.
Definition: format.c:47
void * attribute_data
Attribute specific data, implementation specific.
Definition: format.c:49
unsigned int channel_count
The number if audio channels used, if more than one an interleaved format is required.
Definition: format.c:53
const char * name
Definition: format.c:45
const struct ast_format_interface * interface
Pointer to the optional format interface.
Definition: format.c:51
Support for dynamic strings.
Definition: strings.h:623
Structure used when registering a format interface.
Definition: format.c:57
const struct ast_format_interface * interface
Pointer to the format interface itself.
Definition: format.c:59
char codec[0]
Name of the codec the interface is for.
Definition: format.c:61
int value
Definition: syslog.c:37