Asterisk - The Open Source Telephony Project GIT-master-27fb039
Loading...
Searching...
No Matches
Data Structures | Macros | Functions | Variables
format_ogg_speex.c File Reference

OGG/Speex streams. More...

#include "asterisk.h"
#include "asterisk/mod_format.h"
#include "asterisk/module.h"
#include "asterisk/format_cache.h"
#include <speex/speex_header.h>
#include <ogg/ogg.h>
Include dependency graph for format_ogg_speex.c:

Go to the source code of this file.

Data Structures

struct  speex_desc
 

Macros

#define BLOCK_SIZE   4096 /* buffer size for feeding OGG routines */
 
#define BUF_SIZE   200
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int load_module (void)
 
static void ogg_speex_close (struct ast_filestream *fs)
 Close a OGG/Speex filestream.
 
static int ogg_speex_open (struct ast_filestream *fs)
 Create a new OGG/Speex filestream and set it up for reading.
 
static struct ast_frameogg_speex_read (struct ast_filestream *fs, int *whennext)
 Read a frame full of audio data from the filestream.
 
static int ogg_speex_seek (struct ast_filestream *s, off_t sample_offset, int whence)
 Seek to a specific position in an OGG/Speex filestream.
 
static off_t ogg_speex_tell (struct ast_filestream *s)
 
static int ogg_speex_trunc (struct ast_filestream *s)
 Truncate an OGG/Speex filestream.
 
static int ogg_speex_write (struct ast_filestream *s, struct ast_frame *f)
 
static int read_packet (struct ast_filestream *fs)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "OGG/Speex audio" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_format_def speex16_f
 
static struct ast_format_def speex32_f
 
static struct ast_format_def speex_f
 

Detailed Description

OGG/Speex streams.

Definition in file format_ogg_speex.c.

Macro Definition Documentation

◆ BLOCK_SIZE

#define BLOCK_SIZE   4096 /* buffer size for feeding OGG routines */

Definition at line 39 of file format_ogg_speex.c.

◆ BUF_SIZE

#define BUF_SIZE   200

Definition at line 40 of file format_ogg_speex.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 354 of file format_ogg_speex.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 354 of file format_ogg_speex.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 354 of file format_ogg_speex.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 333 of file format_ogg_speex.c.

334{
338
344 }
345
347}
struct ast_format * ast_format_speex16
Built-in cached speex at 16kHz format.
struct ast_format * ast_format_speex
Built-in cached speex format.
struct ast_format * ast_format_speex32
Built-in cached speex at 32kHz format.
static struct ast_format_def speex32_f
static struct ast_format_def speex_f
static struct ast_format_def speex16_f
static int unload_module(void)
#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_speex, ast_format_speex16, ast_format_speex32, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_format_def::format, speex16_f, speex32_f, speex_f, and unload_module().

◆ ogg_speex_close()

static void ogg_speex_close ( struct ast_filestream fs)
static

Close a OGG/Speex filestream.

Parameters
fsA OGG/Speex filestream.

Definition at line 214 of file format_ogg_speex.c.

215{
216 struct speex_desc *s = (struct speex_desc *)fs->_private;
217
218 ogg_stream_clear(&s->os);
219 ogg_sync_clear(&s->oy);
220}

References ast_filestream::_private, speex_desc::os, and speex_desc::oy.

◆ ogg_speex_open()

static int ogg_speex_open ( struct ast_filestream fs)
static

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

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

Definition at line 130 of file format_ogg_speex.c.

131{
132 char *buffer;
133 size_t bytes;
134 struct speex_desc *s = (struct speex_desc *)fs->_private;
135 SpeexHeader *hdr = NULL;
136 int i, result, expected_rate;
137
138 expected_rate = ast_format_get_sample_rate(fs->fmt->format);
139 s->serialno = -1;
140 ogg_sync_init(&s->oy);
141
142 buffer = ogg_sync_buffer(&s->oy, BLOCK_SIZE);
143 bytes = fread(buffer, 1, BLOCK_SIZE, fs->f);
144 ogg_sync_wrote(&s->oy, bytes);
145
146 result = ogg_sync_pageout(&s->oy, &s->og);
147 if (result != 1) {
148 if(bytes < BLOCK_SIZE) {
149 ast_log(LOG_ERROR, "Run out of data...\n");
150 } else {
151 ast_log(LOG_ERROR, "Input does not appear to be an Ogg bitstream.\n");
152 }
153 ogg_sync_clear(&s->oy);
154 return -1;
155 }
156
157 ogg_stream_init(&s->os, ogg_page_serialno(&s->og));
158 if (ogg_stream_pagein(&s->os, &s->og) < 0) {
159 ast_log(LOG_ERROR, "Error reading first page of Ogg bitstream data.\n");
160 goto error;
161 }
162
163 if (read_packet(fs) < 0) {
164 ast_log(LOG_ERROR, "Error reading initial header packet.\n");
165 goto error;
166 }
167
168 hdr = speex_packet_to_header((char*)s->op.packet, s->op.bytes);
169 if (memcmp(hdr->speex_string, "Speex ", 8)) {
170 ast_log(LOG_ERROR, "OGG container does not contain Speex audio!\n");
171 goto error;
172 }
173 if (hdr->frames_per_packet != 1) {
174 ast_log(LOG_ERROR, "Only one frame-per-packet OGG/Speex files are currently supported!\n");
175 goto error;
176 }
177 if (hdr->nb_channels != 1) {
178 ast_log(LOG_ERROR, "Only monophonic OGG/Speex files are currently supported!\n");
179 goto error;
180 }
181 if (hdr->rate != expected_rate) {
182 ast_log(LOG_ERROR, "Unexpected sampling rate (%d != %d)!\n",
183 hdr->rate, expected_rate);
184 goto error;
185 }
186
187 /* this packet is the comment */
188 if (read_packet(fs) < 0) {
189 ast_log(LOG_ERROR, "Error reading comment packet.\n");
190 goto error;
191 }
192 for (i = 0; i < hdr->extra_headers; i++) {
193 if (read_packet(fs) < 0) {
194 ast_log(LOG_ERROR, "Error reading extra header packet %d.\n", i+1);
195 goto error;
196 }
197 }
198 speex_header_free(hdr);
199
200 return 0;
201error:
202 if (hdr) {
203 speex_header_free(hdr);
204 }
205 ogg_stream_clear(&s->os);
206 ogg_sync_clear(&s->oy);
207 return -1;
208}
#define ast_log
Definition astobj2.c:42
static PGresult * result
Definition cel_pgsql.c:84
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition format.c:379
static int read_packet(struct ast_filestream *fs)
#define BLOCK_SIZE
#define LOG_ERROR
#define NULL
Definition resample.c:96
struct ast_format_def * fmt
Definition mod_format.h:103
int error(const char *format,...)

References ast_filestream::_private, ast_format_get_sample_rate(), ast_log, BLOCK_SIZE, error(), ast_filestream::f, ast_filestream::fmt, ast_format_def::format, LOG_ERROR, NULL, speex_desc::og, speex_desc::op, speex_desc::os, speex_desc::oy, read_packet(), result, and speex_desc::serialno.

◆ ogg_speex_read()

static struct ast_frame * ogg_speex_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 228 of file format_ogg_speex.c.

230{
231 struct speex_desc *s = (struct speex_desc *)fs->_private;
232
233 if (read_packet(fs) < 0) {
234 return NULL;
235 }
236
238 memcpy(fs->fr.data.ptr, s->op.packet, s->op.bytes);
239 fs->fr.datalen = s->op.bytes;
240 fs->fr.samples = *whennext = ast_codec_samples_count(&fs->fr);
241
242 return &fs->fr;
243}
unsigned int ast_codec_samples_count(struct ast_frame *frame)
Get the number of samples contained within a frame.
Definition codec.c:379
#define BUF_SIZE
#define AST_FRAME_SET_BUFFER(fr, _base, _ofs, _datalen)
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
struct ast_frame fr
frame produced by read, typically
Definition mod_format.h:122
union ast_frame::@239 data

References ast_filestream::_private, ast_codec_samples_count(), AST_FRAME_SET_BUFFER, AST_FRIENDLY_OFFSET, ast_filestream::buf, BUF_SIZE, ast_frame::data, ast_frame::datalen, ast_filestream::fr, NULL, speex_desc::op, ast_frame::ptr, read_packet(), and ast_frame::samples.

◆ ogg_speex_seek()

static int ogg_speex_seek ( struct ast_filestream s,
off_t  sample_offset,
int  whence 
)
static

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

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

Definition at line 270 of file format_ogg_speex.c.

271{
272 ast_log(LOG_WARNING, "Seeking is not supported on OGG/Speex streams!\n");
273 return -1;
274}
#define LOG_WARNING

References ast_log, and LOG_WARNING.

◆ ogg_speex_tell()

static off_t ogg_speex_tell ( struct ast_filestream s)
static

Definition at line 276 of file format_ogg_speex.c.

277{
278 ast_log(LOG_WARNING, "Telling is not supported on OGG/Speex streams!\n");
279 return -1;
280}

References ast_log, and LOG_WARNING.

◆ ogg_speex_trunc()

static int ogg_speex_trunc ( struct ast_filestream s)
static

Truncate an OGG/Speex filestream.

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

Definition at line 251 of file format_ogg_speex.c.

252{
253 ast_log(LOG_WARNING, "Truncation is not supported on OGG/Speex streams!\n");
254 return -1;
255}

References ast_log, and LOG_WARNING.

◆ ogg_speex_write()

static int ogg_speex_write ( struct ast_filestream s,
struct ast_frame f 
)
static

Definition at line 257 of file format_ogg_speex.c.

258{
259 ast_log(LOG_WARNING, "Writing is not supported on OGG/Speex streams!\n");
260 return -1;
261}

References ast_log, and LOG_WARNING.

◆ read_packet()

static int read_packet ( struct ast_filestream fs)
static

Definition at line 55 of file format_ogg_speex.c.

56{
57 struct speex_desc *s = (struct speex_desc *)fs->_private;
58 char *buffer;
59 int result;
60 size_t bytes;
61
62 while (1) {
63 /* Get one packet */
64 result = ogg_stream_packetout(&s->os, &s->op);
65 if (result > 0) {
66 if (s->op.bytes >= 5 && !memcmp(s->op.packet, "Speex", 5)) {
67 s->serialno = s->os.serialno;
68 }
69 if (s->serialno == -1 || s->os.serialno != s->serialno) {
70 continue;
71 }
72 return 0;
73 }
74
75 if (result < 0) {
77 "Corrupt or missing data at this page position; continuing...\n");
78 }
79
80 /* No more packets left in the current page... */
81 if (s->eos) {
82 /* No more pages left in the stream */
83 return -1;
84 }
85
86 while (!s->eos) {
87 /* See if OGG has any pages in it's internal buffers */
88 result = ogg_sync_pageout(&s->oy, &s->og);
89 if (result > 0) {
90 /* Read all streams. */
91 if (ogg_page_serialno(&s->og) != s->os.serialno) {
92 ogg_stream_reset_serialno(&s->os, ogg_page_serialno(&s->og));
93 }
94 /* Yes, OGG has more pages in it's internal buffers,
95 add the page to the stream state */
96 result = ogg_stream_pagein(&s->os, &s->og);
97 if (result == 0) {
98 /* Yes, got a new, valid page */
99 if (ogg_page_eos(&s->og) &&
100 ogg_page_serialno(&s->og) == s->serialno)
101 s->eos = 1;
102 break;
103 }
105 "Invalid page in the bitstream; continuing...\n");
106 }
107
108 if (result < 0) {
110 "Corrupt or missing data in bitstream; continuing...\n");
111 }
112
113 /* No, we need to read more data from the file descrptor */
114 /* get a buffer from OGG to read the data into */
115 buffer = ogg_sync_buffer(&s->oy, BLOCK_SIZE);
116 bytes = fread(buffer, 1, BLOCK_SIZE, fs->f);
117 ogg_sync_wrote(&s->oy, bytes);
118 if (bytes == 0) {
119 s->eos = 1;
120 }
121 }
122 }
123}

References ast_filestream::_private, ast_log, BLOCK_SIZE, speex_desc::eos, ast_filestream::f, LOG_WARNING, speex_desc::og, speex_desc::op, speex_desc::os, speex_desc::oy, result, and speex_desc::serialno.

Referenced by ogg_speex_open(), and ogg_speex_read().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 324 of file format_ogg_speex.c.

325{
326 int res = 0;
330 return res;
331}
int ast_format_def_unregister(const char *name)
Unregisters a file format.
Definition file.c:163
char name[80]
Definition mod_format.h:44

References ast_format_def_unregister(), ast_format_def::name, speex16_f, speex32_f, and speex_f.

Referenced by load_module().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "OGG/Speex audio" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND }
static

Definition at line 354 of file format_ogg_speex.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 354 of file format_ogg_speex.c.

◆ speex16_f

struct ast_format_def speex16_f
static

Definition at line 296 of file format_ogg_speex.c.

296 {
297 .name = "ogg_speex16",
298 .exts = "spx16",
299 .open = ogg_speex_open,
300 .write = ogg_speex_write,
301 .seek = ogg_speex_seek,
302 .trunc = ogg_speex_trunc,
303 .tell = ogg_speex_tell,
304 .read = ogg_speex_read,
305 .close = ogg_speex_close,
306 .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
307 .desc_size = sizeof(struct speex_desc),
308};
static int ogg_speex_open(struct ast_filestream *fs)
Create a new OGG/Speex filestream and set it up for reading.
static int ogg_speex_seek(struct ast_filestream *s, off_t sample_offset, int whence)
Seek to a specific position in an OGG/Speex filestream.
static int ogg_speex_write(struct ast_filestream *s, struct ast_frame *f)
static off_t ogg_speex_tell(struct ast_filestream *s)
static struct ast_frame * ogg_speex_read(struct ast_filestream *fs, int *whennext)
Read a frame full of audio data from the filestream.
static int ogg_speex_trunc(struct ast_filestream *s)
Truncate an OGG/Speex filestream.
static void ogg_speex_close(struct ast_filestream *fs)
Close a OGG/Speex filestream.

Referenced by load_module(), and unload_module().

◆ speex32_f

struct ast_format_def speex32_f
static

Definition at line 310 of file format_ogg_speex.c.

310 {
311 .name = "ogg_speex32",
312 .exts = "spx32",
313 .open = ogg_speex_open,
314 .write = ogg_speex_write,
315 .seek = ogg_speex_seek,
316 .trunc = ogg_speex_trunc,
317 .tell = ogg_speex_tell,
318 .read = ogg_speex_read,
319 .close = ogg_speex_close,
320 .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
321 .desc_size = sizeof(struct speex_desc),
322};

Referenced by load_module(), and unload_module().

◆ speex_f

struct ast_format_def speex_f
static

Definition at line 282 of file format_ogg_speex.c.

282 {
283 .name = "ogg_speex",
284 .exts = "spx",
285 .open = ogg_speex_open,
286 .write = ogg_speex_write,
287 .seek = ogg_speex_seek,
288 .trunc = ogg_speex_trunc,
289 .tell = ogg_speex_tell,
290 .read = ogg_speex_read,
291 .close = ogg_speex_close,
292 .buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
293 .desc_size = sizeof(struct speex_desc),
294};

Referenced by load_module(), and unload_module().