Asterisk - The Open Source Telephony Project GIT-master-a358458
Data Structures | Macros | Functions | Variables
format_ogg_vorbis.c File Reference

OGG/Vorbis streams. More...

#include "asterisk.h"
#include <ogg/ogg.h>
#include <vorbis/codec.h>
#include <vorbis/vorbisenc.h>
#include <vorbis/vorbisfile.h>
#include "asterisk/mod_format.h"
#include "asterisk/module.h"
#include "asterisk/format_cache.h"
Include dependency graph for format_ogg_vorbis.c:

Go to the source code of this file.

Data Structures

struct  ogg_vorbis_desc
 

Macros

#define BLOCK_SIZE   4096 /* used internally in the vorbis routines */
 
#define BUF_SIZE   (2*SAMPLES_MAX)
 
#define SAMPLES_MAX   512
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int _ov_header_fseek_wrap (FILE *f, ogg_int64_t off, int whence)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int load_module (void)
 
static void ogg_vorbis_close (struct ast_filestream *fs)
 Close a OGG/Vorbis filestream. More...
 
static int ogg_vorbis_open (struct ast_filestream *s)
 Create a new OGG/Vorbis filestream and set it up for reading. More...
 
static struct ast_frameogg_vorbis_read (struct ast_filestream *fs, int *whennext)
 Read a frame full of audio data from the filestream. More...
 
static int ogg_vorbis_rewrite (struct ast_filestream *s, const char *comment)
 Create a new OGG/Vorbis filestream and set it up for writing. More...
 
static int ogg_vorbis_seek (struct ast_filestream *fs, off_t sample_offset, int whence)
 Seek to a specific position in an OGG/Vorbis filestream. More...
 
static off_t ogg_vorbis_tell (struct ast_filestream *fs)
 Tell the current position in OGG/Vorbis filestream measured in pcms. More...
 
static int ogg_vorbis_trunc (struct ast_filestream *fs)
 Truncate an OGG/Vorbis filestream. More...
 
static int ogg_vorbis_write (struct ast_filestream *fs, struct ast_frame *f)
 Write audio data from a frame to an OGG/Vorbis filestream. More...
 
static int unload_module (void)
 
static void write_stream (struct ogg_vorbis_desc *s, FILE *f)
 Write out any pending encoded data. More...
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "OGG/Vorbis audio" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static ov_callbacks OV_CALLBACKS_NOCLOSE
 
static struct ast_format_def vorbis_f
 

Detailed Description

OGG/Vorbis streams.

Definition in file format_ogg_vorbis.c.

Macro Definition Documentation

◆ BLOCK_SIZE

#define BLOCK_SIZE   4096 /* used internally in the vorbis routines */

Definition at line 56 of file format_ogg_vorbis.c.

◆ BUF_SIZE

#define BUF_SIZE   (2*SAMPLES_MAX)

Definition at line 54 of file format_ogg_vorbis.c.

◆ SAMPLES_MAX

#define SAMPLES_MAX   512

Definition at line 53 of file format_ogg_vorbis.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 449 of file format_ogg_vorbis.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 449 of file format_ogg_vorbis.c.

◆ _ov_header_fseek_wrap()

static int _ov_header_fseek_wrap ( FILE *  f,
ogg_int64_t  off,
int  whence 
)
static

Definition at line 88 of file format_ogg_vorbis.c.

89{
90 if (f == NULL) {
91 return -1;
92 }
93 return fseek(f, off, whence);
94}
#define NULL
Definition: resample.c:96

References NULL.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 449 of file format_ogg_vorbis.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 431 of file format_ogg_vorbis.c.

432{
437}
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
static struct ast_format_def vorbis_f
#define ast_format_def_register(f)
Definition: mod_format.h:136
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
struct ast_format * format
Definition: mod_format.h:48

References ast_format_def_register, ast_format_slin, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_format_def::format, and vorbis_f.

◆ ogg_vorbis_close()

static void ogg_vorbis_close ( struct ast_filestream fs)
static

Close a OGG/Vorbis filestream.

Parameters
fsA OGG/Vorbis filestream.

Definition at line 269 of file format_ogg_vorbis.c.

270{
271 struct ogg_vorbis_desc *s = (struct ogg_vorbis_desc *) fs->_private;
272
273 if (s->writing) {
274 /* Tell the Vorbis encoder that the stream is finished
275 * and write out the rest of the data */
276 vorbis_analysis_wrote(&s->vd, 0);
277 write_stream(s, fs->f);
278
279 /* Cleanup */
280 ogg_stream_clear(&s->os);
281 vorbis_block_clear(&s->vb);
282 vorbis_dsp_clear(&s->vd);
283 vorbis_comment_clear(&s->vc);
284 vorbis_info_clear(&s->vi);
285 } else {
286 /* clear OggVorbis_File handle */
287 ov_clear(&s->ov_f);
288 }
289}
if(!yyg->yy_init)
Definition: ast_expr2f.c:854
static void write_stream(struct ogg_vorbis_desc *s, FILE *f)
Write out any pending encoded data.
void * _private
Definition: mod_format.h:124
vorbis_comment vc
OggVorbis_File ov_f
ogg_stream_state os
int writing
Indicates whether this filestream is set up for reading or writing.
vorbis_dsp_state vd

References ast_filestream::_private, ast_filestream::f, if(), ogg_vorbis_desc::os, ogg_vorbis_desc::ov_f, ogg_vorbis_desc::vb, ogg_vorbis_desc::vc, ogg_vorbis_desc::vd, ogg_vorbis_desc::vi, write_stream(), and ogg_vorbis_desc::writing.

◆ ogg_vorbis_open()

static int ogg_vorbis_open ( struct ast_filestream s)
static

Create a new OGG/Vorbis filestream and set it up for reading.

Parameters
sFile that points to on disk storage of the OGG/Vorbis data.
Returns
The new filestream.

Definition at line 109 of file format_ogg_vorbis.c.

110{
111 int result;
112 struct ogg_vorbis_desc *desc = (struct ogg_vorbis_desc *) s->_private;
113
114 /* initialize private description block */
115 memset(desc, 0, sizeof(struct ogg_vorbis_desc));
116 desc->writing = 0;
117
118 /* actually open file */
119 result = ov_open_callbacks(s->f, &desc->ov_f, NULL, 0, OV_CALLBACKS_NOCLOSE);
120 if (result != 0) {
121 ast_log(LOG_ERROR, "Error opening Ogg/Vorbis file stream.\n");
122 return -1;
123 }
124
125 /* check stream(s) type */
126 if (desc->ov_f.vi->channels != 1) {
127 ast_log(LOG_ERROR, "Only monophonic OGG/Vorbis files are currently supported!\n");
128 ov_clear(&desc->ov_f);
129 return -1;
130 }
131
132 if (desc->ov_f.vi->rate != DEFAULT_SAMPLE_RATE) {
133 ast_log(LOG_ERROR, "Only 8000Hz OGG/Vorbis files are currently supported!\n");
134 ov_clear(&desc->ov_f);
135 return -1;
136 }
137
138 return 0;
139}
#define DEFAULT_SAMPLE_RATE
Definition: asterisk.h:48
#define ast_log
Definition: astobj2.c:42
static const char desc[]
Definition: cdr_radius.c:84
static PGresult * result
Definition: cel_pgsql.c:84
static ov_callbacks OV_CALLBACKS_NOCLOSE
#define LOG_ERROR

References ast_filestream::_private, ast_log, DEFAULT_SAMPLE_RATE, desc, ast_filestream::f, LOG_ERROR, NULL, OV_CALLBACKS_NOCLOSE, and result.

◆ ogg_vorbis_read()

static struct ast_frame * ogg_vorbis_read ( struct ast_filestream fs,
int *  whennext 
)
static

Read a frame full of audio data from the filestream.

Parameters
fsThe filestream.
whennextNumber of sample times to schedule the next call.
Returns
A pointer to a frame containing audio data or NULL ifthere is no more audio data.

Definition at line 297 of file format_ogg_vorbis.c.

299{
300 struct ogg_vorbis_desc *desc = (struct ogg_vorbis_desc *) fs->_private;
301 int current_bitstream = -10;
302 char *out_buf;
303 long bytes_read;
304
305 if (desc->writing) {
306 ast_log(LOG_WARNING, "Reading is not supported on OGG/Vorbis on write files.\n");
307 return NULL;
308 }
309
310 /* initialize frame */
312 out_buf = (char *) (fs->fr.data.ptr); /* SLIN data buffer */
313
314 /* read samples from OV interface */
315 bytes_read = ov_read(
316 &desc->ov_f,
317 out_buf, /* Buffer to write data */
318 BUF_SIZE, /* Size of buffer */
319 (__BYTE_ORDER == __BIG_ENDIAN), /* Endianes (0 for little) */
320 2, /* 1 = 8bit, 2 = 16bit */
321 1, /* 0 = unsigned, 1 = signed */
322 &current_bitstream /* Returns the current bitstream section */
323 );
324
325 /* check returned data */
326 if (bytes_read <= 0) {
327 /* End of stream */
328 return NULL;
329 }
330
331 /* Return decoded bytes */
332 fs->fr.datalen = bytes_read;
333 fs->fr.samples = bytes_read / 2;
334 *whennext = fs->fr.samples;
335 return &fs->fr;
336}
#define __BIG_ENDIAN
Definition: endian.h:49
#define BUF_SIZE
#define AST_FRAME_SET_BUFFER(fr, _base, _ofs, _datalen)
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
#define LOG_WARNING
#define __BYTE_ORDER
struct ast_frame fr
frame produced by read, typically
Definition: mod_format.h:122
union ast_frame::@226 data

References __BIG_ENDIAN, __BYTE_ORDER, ast_filestream::_private, AST_FRAME_SET_BUFFER, AST_FRIENDLY_OFFSET, ast_log, ast_filestream::buf, BUF_SIZE, ast_frame::data, ast_frame::datalen, desc, ast_filestream::fr, if(), LOG_WARNING, NULL, ast_frame::ptr, and ast_frame::samples.

◆ ogg_vorbis_rewrite()

static int ogg_vorbis_rewrite ( struct ast_filestream s,
const char *  comment 
)
static

Create a new OGG/Vorbis filestream and set it up for writing.

Parameters
sFile pointer that points to on-disk storage.
commentComment that should be embedded in the OGG/Vorbis file.
Returns
A new filestream.

Definition at line 147 of file format_ogg_vorbis.c.

149{
150 ogg_packet header;
151 ogg_packet header_comm;
152 ogg_packet header_code;
153 struct ogg_vorbis_desc *tmp = (struct ogg_vorbis_desc *) s->_private;
154
155 tmp->writing = 1;
156 tmp->writing_pcm_pos = 0;
157
158 vorbis_info_init(&tmp->vi);
159
160 if (vorbis_encode_init_vbr(&tmp->vi, 1, DEFAULT_SAMPLE_RATE, 0.4)) {
161 ast_log(LOG_ERROR, "Unable to initialize Vorbis encoder!\n");
162 vorbis_info_clear(&tmp->vi);
163 return -1;
164 }
165
166 vorbis_comment_init(&tmp->vc);
167 vorbis_comment_add_tag(&tmp->vc, "ENCODER", "Asterisk PBX");
168 if (comment)
169 vorbis_comment_add_tag(&tmp->vc, "COMMENT", (char *) comment);
170
171 vorbis_analysis_init(&tmp->vd, &tmp->vi);
172 vorbis_block_init(&tmp->vd, &tmp->vb);
173
174 ogg_stream_init(&tmp->os, ast_random());
175
176 vorbis_analysis_headerout(&tmp->vd, &tmp->vc, &header, &header_comm,
177 &header_code);
178 ogg_stream_packetin(&tmp->os, &header);
179 ogg_stream_packetin(&tmp->os, &header_comm);
180 ogg_stream_packetin(&tmp->os, &header_code);
181
182 while (!tmp->eos) {
183 if (ogg_stream_flush(&tmp->os, &tmp->og) == 0)
184 break;
185 if (fwrite(tmp->og.header, 1, tmp->og.header_len, s->f) != tmp->og.header_len) {
186 ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
187 }
188 if (fwrite(tmp->og.body, 1, tmp->og.body_len, s->f) != tmp->og.body_len) {
189 ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
190 }
191 if (ogg_page_eos(&tmp->og))
192 tmp->eos = 1;
193 }
194
195 return 0;
196}
#define comment
Definition: ael_lex.c:965
static int tmp()
Definition: bt_open.c:389
int errno
long int ast_random(void)
Definition: utils.c:2312

References ast_filestream::_private, ast_log, ast_random(), comment, DEFAULT_SAMPLE_RATE, errno, ast_filestream::f, LOG_ERROR, LOG_WARNING, and tmp().

◆ ogg_vorbis_seek()

static int ogg_vorbis_seek ( struct ast_filestream fs,
off_t  sample_offset,
int  whence 
)
static

Seek to a specific position in an OGG/Vorbis filestream.

Parameters
fsThe filestream to take action on.
sample_offsetNew position for the filestream, measured in 8KHz samples.
whenceLocation to measure
Returns
0 on success, -1 on failure.

Definition at line 377 of file format_ogg_vorbis.c.

378{
379 int seek_result = -1;
380 off_t relative_pcm_pos;
381 struct ogg_vorbis_desc *desc = (struct ogg_vorbis_desc *) fs->_private;
382
383 if (desc->writing) {
384 ast_log(LOG_WARNING, "Seeking is not supported on OGG/Vorbis streams in writing mode!\n");
385 return -1;
386 }
387
388 /* ov_pcm_seek support seeking only from begining (SEEK_SET), the rest must be emulated */
389 switch (whence) {
390 case SEEK_SET:
391 seek_result = ov_pcm_seek(&desc->ov_f, sample_offset);
392 break;
393 case SEEK_CUR:
394 if ((relative_pcm_pos = ogg_vorbis_tell(fs)) < 0) {
395 seek_result = -1;
396 break;
397 }
398 seek_result = ov_pcm_seek(&desc->ov_f, relative_pcm_pos + sample_offset);
399 break;
400 case SEEK_END:
401 if ((relative_pcm_pos = ov_pcm_total(&desc->ov_f, -1)) < 0) {
402 seek_result = -1;
403 break;
404 }
405 seek_result = ov_pcm_seek(&desc->ov_f, relative_pcm_pos - sample_offset);
406 break;
407 default:
408 ast_log(LOG_WARNING, "Unknown *whence* to seek on OGG/Vorbis streams!\n");
409 break;
410 }
411
412 /* normalize error value to -1,0 */
413 return (seek_result == 0) ? 0 : -1;
414}
static off_t ogg_vorbis_tell(struct ast_filestream *fs)
Tell the current position in OGG/Vorbis filestream measured in pcms.

References ast_filestream::_private, ast_log, desc, if(), LOG_WARNING, and ogg_vorbis_tell().

◆ ogg_vorbis_tell()

static off_t ogg_vorbis_tell ( struct ast_filestream fs)
static

Tell the current position in OGG/Vorbis filestream measured in pcms.

Parameters
fsThe filestream to take action on.
Returns
0 or greater with the position measured in samples, or -1 for false.

Definition at line 355 of file format_ogg_vorbis.c.

356{
357 off_t pos;
358 struct ogg_vorbis_desc *desc = (struct ogg_vorbis_desc *) fs->_private;
359
360 if (desc->writing) {
361 return desc->writing_pcm_pos;
362 }
363
364 if ((pos = ov_pcm_tell(&desc->ov_f)) < 0) {
365 return -1;
366 }
367 return pos;
368}

References ast_filestream::_private, desc, and if().

Referenced by ogg_vorbis_seek().

◆ ogg_vorbis_trunc()

static int ogg_vorbis_trunc ( struct ast_filestream fs)
static

Truncate an OGG/Vorbis filestream.

Parameters
fsThe filestream to truncate.
Returns
0 on success, -1 on failure.

Definition at line 344 of file format_ogg_vorbis.c.

345{
346 ast_log(LOG_WARNING, "Truncation is not supported on OGG/Vorbis streams!\n");
347 return -1;
348}

References ast_log, and LOG_WARNING.

◆ ogg_vorbis_write()

static int ogg_vorbis_write ( struct ast_filestream fs,
struct ast_frame f 
)
static

Write audio data from a frame to an OGG/Vorbis filestream.

Parameters
fsAn OGG/Vorbis filestream.
fA frame containing audio to be written to the filestream.
Returns
-1 if there was an error, 0 on success.

Definition at line 235 of file format_ogg_vorbis.c.

236{
237 int i;
238 float **buffer;
239 short *data;
240 struct ogg_vorbis_desc *s = (struct ogg_vorbis_desc *) fs->_private;
241
242 if (!s->writing) {
243 ast_log(LOG_ERROR, "This stream is not set up for writing!\n");
244 return -1;
245 }
246 if (!f->datalen)
247 return -1;
248
249 data = (short *) f->data.ptr;
250
251 buffer = vorbis_analysis_buffer(&s->vd, f->samples);
252
253 for (i = 0; i < f->samples; i++)
254 buffer[0][i] = (double)data[i] / 32768.0;
255
256 vorbis_analysis_wrote(&s->vd, f->samples);
257
258 write_stream(s, fs->f);
259
260 s->writing_pcm_pos += f->samples;
261
262 return 0;
263}
off_t writing_pcm_pos
Stores the current pcm position to support tell() on writing mode.

References ast_filestream::_private, ast_log, ast_frame::data, ast_frame::datalen, ast_filestream::f, if(), LOG_ERROR, ast_frame::ptr, ast_frame::samples, ogg_vorbis_desc::vd, write_stream(), ogg_vorbis_desc::writing, and ogg_vorbis_desc::writing_pcm_pos.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 439 of file format_ogg_vorbis.c.

440{
442}
int ast_format_def_unregister(const char *name)
Unregisters a file format.
Definition: file.c:162
char name[80]
Definition: mod_format.h:44

References ast_format_def_unregister(), ast_format_def::name, and vorbis_f.

◆ write_stream()

static void write_stream ( struct ogg_vorbis_desc s,
FILE *  f 
)
static

Write out any pending encoded data.

Parameters
sAn OGG/Vorbis filestream.
fThe file to write to.

Definition at line 203 of file format_ogg_vorbis.c.

204{
205 while (vorbis_analysis_blockout(&s->vd, &s->vb) == 1) {
206 vorbis_analysis(&s->vb, NULL);
207 vorbis_bitrate_addblock(&s->vb);
208
209 while (vorbis_bitrate_flushpacket(&s->vd, &s->op)) {
210 ogg_stream_packetin(&s->os, &s->op);
211 while (!s->eos) {
212 if (ogg_stream_pageout(&s->os, &s->og) == 0) {
213 break;
214 }
215 if (fwrite(s->og.header, 1, s->og.header_len, f) != s->og.header_len) {
216 ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
217 }
218 if (fwrite(s->og.body, 1, s->og.body_len, f) != s->og.body_len) {
219 ast_log(LOG_WARNING, "fwrite() failed: %s\n", strerror(errno));
220 }
221 if (ogg_page_eos(&s->og)) {
222 s->eos = 1;
223 }
224 }
225 }
226 }
227}
int eos
Indicates whether an End of Stream condition has been detected.

References ast_log, ogg_vorbis_desc::eos, errno, LOG_WARNING, NULL, ogg_vorbis_desc::og, ogg_vorbis_desc::op, ogg_vorbis_desc::os, ogg_vorbis_desc::vb, and ogg_vorbis_desc::vd.

Referenced by ast_write_stream(), ogg_vorbis_close(), ogg_vorbis_write(), and tech_write().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "OGG/Vorbis audio" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND }
static

Definition at line 449 of file format_ogg_vorbis.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 449 of file format_ogg_vorbis.c.

◆ OV_CALLBACKS_NOCLOSE

ov_callbacks OV_CALLBACKS_NOCLOSE
static

Definition at line 96 of file format_ogg_vorbis.c.

Referenced by ogg_vorbis_open().

◆ vorbis_f

struct ast_format_def vorbis_f
static

Definition at line 416 of file format_ogg_vorbis.c.

Referenced by load_module(), and unload_module().