Asterisk - The Open Source Telephony Project GIT-master-f36a736
slinfactory.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2005, Anthony Minessale II.
5 *
6 * Anthony Minessale <anthmct@yahoo.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 A machine to gather up arbitrary frames and convert them
22 * to raw slinear on demand.
23 *
24 * \author Anthony Minessale <anthmct@yahoo.com>
25 */
26
27/*** MODULEINFO
28 <support_level>core</support_level>
29 ***/
30
31#include "asterisk.h"
32
33#include "asterisk/frame.h"
36#include "asterisk/translate.h"
37#include "asterisk/astobj2.h"
38
40{
41 memset(sf, 0, sizeof(*sf));
42 sf->offset = sf->hold;
44}
45
47{
48 memset(sf, 0, sizeof(*sf));
49 sf->offset = sf->hold;
50 if (!ast_format_cache_is_slinear(slin_out)) {
51 return -1;
52 }
53 sf->output_format = ao2_bump(slin_out);
54
55 return 0;
56}
57
59{
60 struct ast_frame *f;
61
62 if (sf->trans) {
64 sf->trans = NULL;
65 }
66
67 while ((f = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list))) {
68 ast_frfree(f);
69 }
70
72 sf->output_format = NULL;
74 sf->format = NULL;
75}
76
78{
79 struct ast_frame *begin_frame = f, *duped_frame = NULL, *frame_ptr;
80 unsigned int x = 0;
81
82 /* In some cases, we can be passed a frame which has no data in it, but
83 * which has a positive number of samples defined. Once such situation is
84 * when a jitter buffer is in use and the jitter buffer interpolates a frame.
85 * The frame it produces has data set to NULL, datalen set to 0, and samples
86 * set to either 160 or 240.
87 */
88 if (!f->data.ptr) {
89 return 0;
90 }
91
95 sf->trans = NULL;
96 }
97
98 if (!sf->trans) {
100 ast_log(LOG_WARNING, "Cannot build a path from %s (%u)to %s (%u)\n",
105 return 0;
106 }
108 }
109
110 if (!(begin_frame = ast_translate(sf->trans, f, 0))) {
111 return 0;
112 }
113
114 if (!(duped_frame = ast_frisolate(begin_frame))) {
115 return 0;
116 }
117
118 if (duped_frame != begin_frame) {
119 ast_frfree(begin_frame);
120 }
121 } else {
122 if (sf->trans) {
124 sf->trans = NULL;
125 }
126 if (!(duped_frame = ast_frdup(f)))
127 return 0;
128 }
129
130 AST_LIST_TRAVERSE(&sf->queue, frame_ptr, frame_list) {
131 x++;
132 }
133
134 /* if the frame was translated, the translator may have returned multiple
135 frames, so process each of them
136 */
137 for (begin_frame = duped_frame; begin_frame; begin_frame = AST_LIST_NEXT(begin_frame, frame_list)) {
138 AST_LIST_INSERT_TAIL(&sf->queue, begin_frame, frame_list);
139 sf->size += begin_frame->samples;
140 }
141
142 return x;
143}
144
145int ast_slinfactory_read(struct ast_slinfactory *sf, short *buf, size_t samples)
146{
147 struct ast_frame *frame_ptr;
148 unsigned int sofar = 0, ineed, remain;
149 short *frame_data, *offset = buf;
150
151 while (sofar < samples) {
152 ineed = samples - sofar;
153
154 if (sf->holdlen) {
155 if (sf->holdlen <= ineed) {
156 memcpy(offset, sf->offset, sf->holdlen * sizeof(*offset));
157 sofar += sf->holdlen;
158 offset += sf->holdlen;
159 sf->holdlen = 0;
160 sf->offset = sf->hold;
161 } else {
162 remain = sf->holdlen - ineed;
163 memcpy(offset, sf->offset, ineed * sizeof(*offset));
164 sofar += ineed;
165 sf->offset += ineed;
166 sf->holdlen = remain;
167 }
168 continue;
169 }
170
171 if ((frame_ptr = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list))) {
172 frame_data = frame_ptr->data.ptr;
173
174 if (frame_ptr->samples <= ineed) {
175 memcpy(offset, frame_data, frame_ptr->samples * sizeof(*offset));
176 sofar += frame_ptr->samples;
177 offset += frame_ptr->samples;
178 } else {
179 remain = frame_ptr->samples - ineed;
180 memcpy(offset, frame_data, ineed * sizeof(*offset));
181 sofar += ineed;
182 frame_data += ineed;
183 if (remain > (AST_SLINFACTORY_MAX_HOLD - sf->holdlen)) {
184 remain = AST_SLINFACTORY_MAX_HOLD - sf->holdlen;
185 }
186 memcpy(sf->hold, frame_data, remain * sizeof(*offset));
187 sf->holdlen = remain;
188 }
189 ast_frfree(frame_ptr);
190 } else {
191 break;
192 }
193 }
194
195 sf->size -= sofar;
196 return sofar;
197}
198
199unsigned int ast_slinfactory_available(const struct ast_slinfactory *sf)
200{
201 return sf->size;
202}
203
205{
206 struct ast_frame *fr = NULL;
207
208 if (sf->trans) {
210 sf->trans = NULL;
211 }
212
213 while ((fr = AST_LIST_REMOVE_HEAD(&sf->queue, frame_list)))
214 ast_frfree(fr);
215
216 sf->size = sf->holdlen = 0;
217 sf->offset = sf->hold;
218
219 return;
220}
Asterisk main include file. File version handling, generic pbx functions.
#define ast_log
Definition: astobj2.c:42
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:501
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
unsigned int ast_format_get_codec_id(const struct ast_format *format)
Get the codec identifier associated with a format.
Definition: format.c:329
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
@ AST_FORMAT_CMP_NOT_EQUAL
Definition: format.h:38
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
Media Format Cache API.
int ast_format_cache_is_slinear(struct ast_format *format)
Determines if a format is one of the cached slin formats.
Definition: format_cache.c:534
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
Asterisk internal frame definitions.
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
#define ast_frdup(fr)
Copies a frame.
#define ast_frfree(fr)
#define LOG_WARNING
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
#define NULL
Definition: resample.c:96
void ast_slinfactory_init(struct ast_slinfactory *sf)
Initialize a slinfactory.
Definition: slinfactory.c:39
int ast_slinfactory_init_with_format(struct ast_slinfactory *sf, struct ast_format *slin_out)
Initialize a slinfactory.
Definition: slinfactory.c:46
unsigned int ast_slinfactory_available(const struct ast_slinfactory *sf)
Retrieve number of samples currently in a slinfactory.
Definition: slinfactory.c:199
int ast_slinfactory_read(struct ast_slinfactory *sf, short *buf, size_t samples)
Read samples from a slinfactory.
Definition: slinfactory.c:145
void ast_slinfactory_flush(struct ast_slinfactory *sf)
Flush the contents of a slinfactory.
Definition: slinfactory.c:204
int ast_slinfactory_feed(struct ast_slinfactory *sf, struct ast_frame *f)
Feed audio into a slinfactory.
Definition: slinfactory.c:77
void ast_slinfactory_destroy(struct ast_slinfactory *sf)
Destroy the contents of a slinfactory.
Definition: slinfactory.c:58
A machine to gather up arbitrary frames and convert them to raw slinear on demand.
#define AST_SLINFACTORY_MAX_HOLD
Definition: slinfactory.h:33
Definition of a media format.
Definition: format.c:43
struct ast_format * format
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@226 data
short * offset
Definition: slinfactory.h:39
struct ast_format * output_format
Definition: slinfactory.h:43
unsigned int size
Definition: slinfactory.h:41
struct ast_format * format
Definition: slinfactory.h:42
struct ast_trans_pvt * trans
Definition: slinfactory.h:37
short hold[AST_SLINFACTORY_MAX_HOLD]
Definition: slinfactory.h:38
Support for translation of data formats. translate.c.
struct ast_frame * ast_translate(struct ast_trans_pvt *tr, struct ast_frame *f, int consume)
translates one or more frames Apply an input frame into the translator and receive zero or one output...
Definition: translate.c:566
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:476
struct ast_trans_pvt * ast_translator_build_path(struct ast_format *dest, struct ast_format *source)
Builds a translator path Build a path (possibly NULL) from source to dest.
Definition: translate.c:486