Asterisk - The Open Source Telephony Project  18.5.0
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. More...
 
static int ogg_speex_open (struct ast_filestream *fs)
 Create a new OGG/Speex filestream and set it up for reading. More...
 
static struct ast_frameogg_speex_read (struct ast_filestream *fs, int *whennext)
 Read a frame full of audio data from the filestream. More...
 
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. More...
 
static off_t ogg_speex_tell (struct ast_filestream *s)
 
static int ogg_speex_trunc (struct ast_filestream *s)
 Trucate an OGG/Speex filestream. More...
 
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 = "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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .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.

Referenced by ogg_speex_open(), and read_packet().

◆ BUF_SIZE

#define BUF_SIZE   200

Definition at line 40 of file format_ogg_speex.c.

Referenced by ogg_speex_read().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 345 of file format_ogg_speex.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 345 of file format_ogg_speex.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 345 of file format_ogg_speex.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 324 of file format_ogg_speex.c.

References ast_format_def_register, ast_format_speex, ast_format_speex16, ast_format_speex32, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_APP_DEPEND, AST_MODULE_INFO(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, AST_MODULE_SUPPORT_EXTENDED, ASTERISK_GPL_KEY, ast_format_def::format, and unload_module().

325 {
329 
333  unload_module();
335  }
336 
338 }
static struct ast_format_def speex32_f
#define ast_format_def_register(f)
Definition: mod_format.h:136
struct ast_format * ast_format_speex16
Built-in cached speex at 16kHz format.
Definition: format_cache.c:141
struct ast_format * format
Definition: mod_format.h:48
static struct ast_format_def speex16_f
struct ast_format * ast_format_speex
Built-in cached speex format.
Definition: format_cache.c:136
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static struct ast_format_def speex_f
static int unload_module(void)
struct ast_format * ast_format_speex32
Built-in cached speex at 32kHz format.
Definition: format_cache.c:146

◆ 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.

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

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 }
ogg_sync_state oy
void * _private
Definition: mod_format.h:124
ogg_stream_state os

◆ 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.

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.

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;
201 error:
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 }
ogg_sync_state oy
ogg_packet op
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
static int read_packet(struct ast_filestream *fs)
struct ast_format_def * fmt
Definition: mod_format.h:103
#define BLOCK_SIZE
struct ast_format * format
Definition: mod_format.h:48
void * _private
Definition: mod_format.h:124
#define LOG_ERROR
Definition: logger.h:285
ogg_stream_state os
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 PGresult * result
Definition: cel_pgsql.c:88
int error(const char *format,...)
Definition: utils/frame.c:999

◆ 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.

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, if(), NULL, speex_desc::op, ast_frame::ptr, read_packet(), and ast_frame::samples.

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 }
ogg_packet op
if(!yyg->yy_init)
Definition: ast_expr2f.c:868
#define NULL
Definition: resample.c:96
#define BUF_SIZE
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
static int read_packet(struct ast_filestream *fs)
struct ast_frame fr
frame produced by read, typically
Definition: mod_format.h:122
unsigned int ast_codec_samples_count(struct ast_frame *frame)
Get the number of samples contained within a frame.
Definition: codec.c:378
void * _private
Definition: mod_format.h:124
#define AST_FRAME_SET_BUFFER(fr, _base, _ofs, _datalen)
union ast_frame::@263 data

◆ 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 264 of file format_ogg_speex.c.

References ast_log, and LOG_WARNING.

265 {
266  ast_log(LOG_WARNING, "Seeking is not supported on OGG/Speex streams!\n");
267  return -1;
268 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42

◆ ogg_speex_tell()

static off_t ogg_speex_tell ( struct ast_filestream s)
static

Definition at line 270 of file format_ogg_speex.c.

References ast_log, and LOG_WARNING.

271 {
272  ast_log(LOG_WARNING, "Telling is not supported on OGG/Speex streams!\n");
273  return -1;
274 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42

◆ ogg_speex_trunc()

static int ogg_speex_trunc ( struct ast_filestream s)
static

Trucate 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.

References ast_log, and LOG_WARNING.

252 {
253  ast_log(LOG_WARNING, "Truncation is not supported on OGG/Speex streams!\n");
254  return -1;
255 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42

◆ read_packet()

static int read_packet ( struct ast_filestream fs)
static

Definition at line 55 of file format_ogg_speex.c.

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, speex_desc::serialno, and while().

Referenced by ogg_speex_open(), and ogg_speex_read().

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 }
ogg_sync_state oy
ogg_packet op
#define LOG_WARNING
Definition: logger.h:274
int eos
Indicates whether an End of Stream condition has been detected.
#define ast_log
Definition: astobj2.c:42
while(1)
Definition: ast_expr2f.c:894
#define BLOCK_SIZE
void * _private
Definition: mod_format.h:124
ogg_stream_state os
static PGresult * result
Definition: cel_pgsql.c:88

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 315 of file format_ogg_speex.c.

References ast_format_def_unregister(), and ast_format_def::name.

Referenced by load_module().

316 {
317  int res = 0;
321  return res;
322 }
static struct ast_format_def speex32_f
int ast_format_def_unregister(const char *name)
Unregisters a file format.
Definition: file.c:162
static struct ast_format_def speex16_f
char name[80]
Definition: mod_format.h:44
static struct ast_format_def speex_f

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "OGG/Speex 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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND }
static

Definition at line 345 of file format_ogg_speex.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 345 of file format_ogg_speex.c.

◆ speex16_f

struct ast_format_def speex16_f
static

Definition at line 289 of file format_ogg_speex.c.

◆ speex32_f

struct ast_format_def speex32_f
static

Definition at line 302 of file format_ogg_speex.c.

◆ speex_f

struct ast_format_def speex_f
static

Definition at line 276 of file format_ogg_speex.c.